Paramiko, channel.recv(9999) causing confusion [duplicate] - ssh

I am using Python's Paramiko library to SSH a remote machine and fetch some output from command-line. I see a lot of junk printing along with the actual output. How to get rid of this?
chan1.send("ls\n")
output = chan1.recv(1024).decode("utf-8")
print(output)
[u'Last login: Wed Oct 21 18:08:53 2015 from 172.16.200.77\r', u'\x1b[2J\x1b[1;1H[local]cli#BENU>enable', u'[local]cli#BENU#Configure',
I want to eliminate, [2J\x1b[1;1H and u from the output. They are junk.

It's not a junk. These are ANSI escape codes that are normally interpreted by a terminal client to pretty print the output.
If the server is correctly configured, you get these only, when you use an interactive terminal, in other words, if you requested a pseudo terminal for the session (what you should not, if you are automating the session).
The Paramiko automatically requests the pseudo terminal, if you used the SSHClient.invoke_shell, as that is supposed to be used for implementing an interactive terminal. See also How do I start a shell without terminal emulation in Python Paramiko?
If you automate an execution of remote commands, you better use the SSHClient.exec_command, which does not allocate the pseudo terminal by default (unless you override by the get_pty=True argument).
stdin, stdout, stderr = client.exec_command('ls')
See also What is the difference between exec_command and send with invoke_shell() on Paramiko?
Or as a workaround, see How can I remove the ANSI escape sequences from a string in python.
Though that's rather a hack and might not be sufficient. You might have other problems with the interactive terminal, not only the escape sequences.
You particularly are probably not interested in the "Last login" message and command-prompt (cli#BENU>) either. You do not get these with the exec_command.
If you need to use the "shell" channel due to some specific requirements or limitations of the server, note that it is technically possible to use the "shell" channel without the pseudo terminal. But Paramiko SSHClient.invoke_shell does not allow that. Instead, you can create the "shell" channel manually. See Can I call Channel.invoke_shell() without calling Channel.get_pty() beforehand, when NOT using Channel.exec_command().
And finally the u is not a part of the actual string value (note that it's outside the quotes). It's an indication that the string value is in the Unicode encoding. You want that!

This is actually not junk. The u before the string indicates that this is a unicode string. The \x1b[2J\x1b[1;1H is an escape sequence. I don't know exactly what it is supposed to do, but it appears to clear the screen when I print it out.
To see what I mean, try this code:
for string in output:
print string

Related

Run a binary CGI file on the command line with GET params

How can I run a binary cgi file on the command line and provide GET parameters to it?
I understand this task may be straightforward for perl or php files, but I've got a binary cgi file and no documentation for it. I'd like to run it without a web server so that I can evaluate certain problems on some co-workers' machines.
I've tried the following, but to no avail:
QUERY_STRING="foo=bar" ./myfile.cgi
foo=bar ./myfile.cgi
./myfile.cgi foo=bar
./myfile.cgi <<< "foo=bar"
In each case, the script outputs Error in form found<br>Missing foo<br><b></b><br>. (When executed through apache on our server, it returns no error message, only the intended results.)
Specifying the environment variable REQUEST_METHOD=GET in addition to QUERY_STRING=... makes the difference.
Among the tokens output by strings myfile.cgi, there were a number of cgi-related variables which the web server might be expected to set, such as REMOTE_ADDR, SERVER_SOFTWARE, and SERVER_PROTOCOL, but the two aforementioned variables proved enough to get this executable to produce a non-error output.
(For a POST, I've read that the body/params are read from stdin, but I haven't substantiated that personally.)

Capture image from oscilloscope and store on PC using LabVIEW

I am trying to remotely control an oscilloscope from Agilent (DSO-X 3034A) using LabVIEW. I want to take a screen capture and store it on the computer. I tried the following:
The commands inside the string are:
:SAVE:FILename "temp.png";:SAVE:IMAGe:FACTors ON;:SAVE:IMAGe:FORMat PNG;:SAVE:IMAGe:INKSaver OFF;:SAVE:IMAGe:STARt;
I get the following errors:
Thank you
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ EDIT ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
I managed to save the image on the oscilloscope. I am currently trying to move it and save it on the computer instead. I tried the following:
However after writing the "HARDcopy" commands I get the following error:
Your header is undefined. Refer to the "Serial Communications" documentation in order to see what the instrument is expecting in the header. You should right click your string constant and do "\ Codes Display" so that if the documentation calls for a \n character, you're not accidentally sending a \ character followed by an n character.
Query Unterminated means you're not terminating the query as the instrument expects. It looks like you have a newline, but assuming you're using windows, it's possible that the instrument doesn't want the extra \r that is there by default. Again, you'll have to refer to the documentation to be sure.

How to interact with an external command in vimscript?

I have a script which interacts with user (prints some questions to stderr and gets input from stdin) and then prints some data to stdin. I want to put the output of the script to a variable in vimscript. It probably should look like this:
let a = system("./script")
The supposed behavior is that script runs, interacts with user, and after all a is assigned with its output to stdout. But instead a is assigned both with outputs to stdout and stderr, so user seed no prompts.
Could you help me fixing it?
Interactive commands are best avoided from within Vim; especially with GVIM (on Windows), a new console window pops up; you may not have a fully functional terminal, ...
Better query any needed arguments in Vimscript itself (with input(); or pass them on from a custom Vim :command), and just use the external script non-interactively, feeding it everything it needs.
What gets captured by system() (as well as :!) is controlled by the 'shellredir' option. Its usual value, >%s 2>&1 captures stdout as well as stderr. Your script needs to choose one (e.g. stdout) for its output, and the other for user interaction, and the Vimscript wrapper that invokes it must (temporarily) change the option.
:let save_shellredir = &shellredir
:set shellredir=>
:let a = system('./script') " The script should interact via stderr.
:let &shellredir = save_shellredir
Call the script within the other as,
. ./script.sh
I think this is what you meant.

DB upload in mysql - loses UTF characters

I'm frequently updating my db on the server, and I run the following line from the command line:
mysqldump -u root --password=mypass mydb|mysql -h mysite.cc -u remotusr --password=remotpsw remotdb
The problem is that it loses the UTF characters along the way.
How can I keep the utf chars in cmd, or what is a better practice doing this?
( Upgrading to an answer )
As documented under mysqldump — A Database Backup Program:
--default-character-set=charset_name
Use charset_name as the default character set. See Section 10.5, “Character Set Configuration”. If no character set is specified, mysqldump uses utf8, and earlier versions use latin1.
[ deletia ]
--set-charset
Add SET NAMES default_character_set to the output. This option is enabled by default. To suppress the SET NAMES statement, use --skip-set-charset.
Therefore, unless you have settings in an option file which are overriding these defaults (you can specify --no-defaults to ensure they are not), the output from mysqldump should be more than capable of being redirected to another mysql session without loss of Unicode characters.
Instead, the conversion to a smaller character set appears to be occurring on retrieving & displaying your data from the new database. Since you are using PHP's Original MySQL API for this purpose, despite the warning in the introduction to its manual chapter (below), you should use mysql_set_charset() to set the connection character set.
This extension is not recommended for writing new code. Instead, either the mysqli or PDO_MySQL extension should be used. See also the MySQL API Overview for further help while choosing a MySQL API.

limitations of #! in scripts

It seems as if a script with #! prefix can have the interpreter name and ONLY one argument. Thus:
#!/bin/ls -l
works, but
#!/usr/bin/env ls -l
doesn't
Do you agree? Any thoughts?
Francesc
Different Unixes interpret #! differently. Here's a comprehensive-looking writeup: http://www.in-ulm.de/~mascheck/various/shebang/
It seems that the lowest common denominator across platforms is "the interpreter (which must not itself be a script) and no more than one argument".
Originally, we only had one shell on Unix. When you asked to run a command, the shell would attempt to invoke one of the exec() system calls on it. It the command was an executable, the exec would succeed and the command would run. If the exec() failed, the shell would not give up, instead it would try to interpret the command file as if it were a shell script.
Then unix got more shells and the situation became confused. Most folks would write scripts in one shell and type commands in another. And each shell had differing rules for feeding scripts to an interpreter.
This is when the “#! /” trick was invented. The idea was to let the kernel’s exec () system calls succeed with shell scripts. When the kernel tries to exec () a file, it looks at the first 4 bytes which represent an integer called a magic number. This tells the kernel if it should try to run the file or not. So “#! /” was added to magic numbers that the kernel knows and it was extended to actually be able to run shell scripts by itself. But some people could not type “#! /”, they kept leaving the space out. So the kernel was expended a bit again to allow “#!/” to work as a special 3 byte magic number.