Can sqlcmd be configured support ANSI escape sequences (for coloring PRINT output) - sqlcmd

I am running a .sql script through sqlcmd in a cmd shell and would like the script to emit my PRINT output in color.
How to echo with different colors in the Windows command line demonstrates how the Windows 10 CMD supports ANSI escape sequences.
I am guessing sqlcmd runs it's own cmd shell because the colors don't appear.
sqlcmd -S (LocalDB)\MSSQLLocalDB
> print 'NOTE: my message'
> go
NOTE: my message <--- Appears white on black.
In the next print there is ^[.
^[ is how the command shell renders a literal escape character.
The literal escape is entered from the keyboard using key combination Alt-Keypad 027.
> print '^[92mNOTE: my message ^[0m'
> go
□92mNOTE: my message□0m <--- Would like this to appear bright green on black
The sqlcmd shell is not supporting ANSI escape sequences. The escape character is output as a box (□) glyph and 92m sequence for bright green does not get interpreted.
Can the sqlcmd shell be configured to support the ANSI escape sequences?
I am using Windows 10 and SQLExpress 2016.
>sqlcmd -?
Microsoft (R) SQL Server Command Line Tool
Version 11.0.2100.60 NT x64
Copyright (c) 2012 Microsoft. All rights reserved.

A closer read of [sqlcmd utility documentation][1] under "Miscellaneous Commands" shows the feature
[:] !!< command> Executes operating system commands.
So the ECHO command can be issued with ANSI escape sequences to get coloring
:!!ECHO <alt-027>[1;32mThis is bright green.<alt-027>[0m This is not.

Related

Perl gives "gzip: stdout: Broken pipe" error when opening gzipped files, but only if connecting to a DB

Consider the following program, running on a Linux machine, which opens a gzipped input file:
#!/usr/bin/env perl
open (my $fileHandle, "-|", "/bin/zcat $ARGV[0]");
my $ff = <$fileHandle>;
close($fileHandle);
That works as expected (it does nothing, but prints no error):
$ bar.pl file.gz
$
Now, if I use the same code but previously connect to a MySQL database, gzip will complain (you can run the code directly, this is an open DB and the credentials will work):
#!/usr/bin/env perl
use DBI;
use strict;
use warnings;
my $dsn = "DBI:mysql:database=hg19;host=genome-mysql.cse.ucsc.edu";
my $db = DBI->connect($dsn, 'genomep', 'password');
my $dbResults = $db->prepare("show tables");
my $ret = $dbResults->execute();
$dbResults->finish();
$db->disconnect();
open (my $fileHandle, "-|", "/bin/zcat $ARGV[0]");
my $ff = <$fileHandle>;
close($ff);
Running the above gives:
$ foo.pl file.gz
gzip: stdout: Broken pipe
This is obviously part of a much more complicated program, but I've managed to trim it down to this silly snippet that reproduces the issue.
What's going on? Why does connecting to a DB affect how gzip behaves? Note that everything seems to work (in the actual program, I do something useful with the gzipped data) but why am I getting that error message?
It turns out this behavior is specific to (slightly) older versions of Perl and/or DBI. On the machines where it failed, I have:
Ubuntu
Perl 5, version 22, subversion 1 (v5.22.1) built for x86_64-linux-gnu-thread-multi
DBI 1.634
DBD 4.033
gzip 1.6
However, on another two machines it did work. These had:
Ubuntu
Perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-gnu-thread-multi
DBI 1.640
DBD 4.033
gzip 1.6
And
Arch Linux
Perl 5, version 30, subversion 0 (v5.30.0) built for x86_64-linux-thread-multi
DBI 1.642
DBD 4.050
gzip 1.10
At least here, it appears that the MySQL libraries (probably) are masking (ignoring) SIGPIPE, and that's what you're seeing. Comparing strace outputs, I see a line like this in the MySQL run:
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f78bdf16840}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
And it turns out you can duplicate the behavior easily w/o MySQL:
$SIG{PIPE} = 'IGNORE';
open (my $fileHandle, "-|", "/bin/zcat $ARGV[0]");
my $ff = <$fileHandle>;
close($ff);
Or, alternatively, you can reset the signal to the default handler to make the message go away, even after connecting to MySQL by setting it to DEFAULT instead of IGNORE.
This is, by the way, documented behavior of the MySQL library:
To avoid aborting the program when a connection terminates, MySQL blocks SIGPIPE on the first call to mysql_library_init(), mysql_init(), or mysql_connect().
(It may also depend on the gzip version; maybe some versions of gzip set up signal handlers on init.)
Ultimately, what you're seeing is that if gzip gets a SIGPIPE, it just exits. If it gets an error back from write (because SIGPIPE is ignored), it prints an error message.
Most probably the following is happening:
gzip tries to write to the pipe, the program on your side is not reading up to eof, the closes the pipe. Gzip then receives a SIGPIPE, and dies with this error message. Can you confirm that this is taking place?

How to import/load/run mysql file using golang?

I’m trying to run/load sql file into mysql database using this golang statement but this is not working:
exec.Command("mysql", "-u", "{username}", "-p{db password}", "{db name}", "<", file abs path )
But when i use following command in windows command prompt it’s working perfect.
mysql -u {username} -p{db password} {db name} < {file abs path}
So what is the problem?
As others have answered, you can't use the < redirection operator because exec doesn't use the shell.
But you don't have to redirect input to read an SQL file. You can pass arguments to the MySQL client to use its source command.
exec.Command("mysql", "-u", "{username}", "-p{db password}", "{db name}",
"-e", "source {file abs path}" )
The source command is a builtin of the MySQL client. See https://dev.mysql.com/doc/refman/5.7/en/mysql-commands.html
Go's exec.Command runs the first argument as a program with the rest of the arguments as parameters. The '<' is interpreted as a literal argument.
e.g. exec.Command("cat", "<", "abc") is the following command in bash: cat \< abc.
To do what you want you have got two options.
Run (ba)sh and the command as argument: exec.Command("bash", "-c", "mysql ... < full/path")
Pipe the content of the file in manually. See https://stackoverflow.com/a/36383984/8751302 for details.
The problem with the bash version is that is not portable between different operating systems. It won't work on Windows.
Go's os.exec package does not use the shell and does not support redirection:
Unlike the "system" library call from C and other languages, the os/exec package intentionally does not invoke the system shell and does not expand any glob patterns or handle other expansions, pipelines, or redirections typically done by shells.
You can call the shell explicitly to pass arguments to it:
cmd := exec.Command("/bin/sh", yourBashCommand)
Depending on what you're doing, it may be helpful to write a short bash script and call it from Go.

TCL + Expect Windows 8 64-bit

I want to use TCL with Expect at my Windows 8 64-bit OS
I've installed 32-bit version of TCL from ActiveState, installed Expect via teacup, and use 32-bit version of plink (cause native Windows Telnet client doesnt work).
Testing scripts actully work, but they print no output to console, just run silently.
Here is example
package require Expect
log_user 1
spawn plink -telnet -P 2001 10.10.10.100
send "conf t\r"
send "hostname yyyy\r"
send "int loo100\r"
send "int loo101\r"
send "int loo102\r"
send "exit\r"
If i run it directly from shell command by command i receive just some number after spawn. Please, look at screenshot.
What is the problem ?
Tnkx

Error passing large text with special characters in a variable to MYSQL

I have an script that connects with SSH to a remote Host, and executes another script there which inserts data into a local MySQL database. I pass all the variables that need to be inserted within the SSH. All works fine excepts for the $textBody variable.I think the problem is that there ara a lot of text in this variable (included special characters that may be causing the error).
ssh -p 22 $user#$IP_ADDRESS "$SCRIPTMYSQL \"$taulaName\" \"$valueType\" \"$valueTitle\" \"$textBODY\" exit"
This is the error I get:
jailshell: -u: command not found
ERROR at line 1: Unknown command '\S'.
If I pass another variable different than $textBODY in his place, no error occurs.
I'm passing double quotes inside the variable.
If $textBODY doesn't contain single quotes ', you can use them:
ssh -p 22 $user#$IP_ADDRESS "$SCRIPTMYSQL \"$taulaName\" \"$valueType\" \"$valueTitle\" '$textBODY' exit"
(that also applies to the other variables, of course).

What is the equivalent of the spool command in MySQL?

I know you use the spool command when you are trying to write a report to a file in Oracle SQLplus.
What is the equivalent command in MySQL?
This is my code:
set termout off
spool ${DB_ADMIN_HOME}/data/Datareport.log # ${DB_ADMIN_HOME}/Scripts.Datavalidation/Datareportscript.sql
spool off
exit
How can I write it in MySQL?
In MySQL you need to use the commands tee & notee:
tee data.txt;
//SQL sentences...
notee;
teedata.txt == spooldata.txt
notee == spool off
For the Oracle SQLPlus spool command, there is no equivalent in the mysql command line client.
To get output from the mysql command line client saved to a file, you can have the operating system redirect the output to a file, rather than to the display.
In Unix, you use the > symbol on the command line. (It seems a bit redundant here to give an example of how to redirect output.)
date > /tmp/foo.txt
That > symbol is basically telling the shell to take what is written to the STDOUT handle and redirect that to the named file (overwriting the file if it exists) if you have privileges.
Q: is set pagesize and set linesize used in mysql when you are trying to generate a report?
A: No. Those are specific to Oracle SQLPlus. I don't know of any equivalent functionality in the mysql command line client. The mysql command line client has some powerful features when its run in interactive mode (e.g. pager and tee), but in non-interactive mode, it's an inadequate replacement for SQLPlus.
If I get what you are asking:
mysql dbname < ${DB_ADMIN_HOME}/Scripts.Datavalidation/Datareportscript.sql \
> ${DB_ADMIN_HOME}/data/Datareport.log
Use redirection.