Foundations of Python Network Programming

(WallPaper) #1
Chapter 16 ■ telnet and SSh

295

Every one of these responses is reasonable, as you can demonstrate to yourself. First use echo to see what each
command looks like when quoted by the local shell and then paste that text into a remote SSH command line to see
how the processed text is handled there. However, these commands can be tricky to write, and even a practiced Unix
shell scripter can guess wrong when trying to predict the output from the foregoing series of commands!


The Terrible Windows Command Line

Did you enjoy reading the previous sections on the Unix shell and how arguments are ultimately delivered to a
process? Well, if you are going to be connecting to a Windows machine using a remote-shell protocol, then you can
forget everything you have just read. Windows is amazingly primitive. Instead of delivering command-line arguments
to a new process as separate strings, it simply hands over the text of the entire command line to the new process that
is starting up and makes the process try to figure out itself how the user might have quoted file names with spaces
in them!
Of course, merely to survive, people in the Windows world have adopted more or less consistent traditions
about how commands will interpret their arguments. For example, you can put double quotes around a multiword
file name and expect nearly all programs to recognize that you are naming one file, not several. Most commands also
try to understand that asterisks in a file name are wildcards. But this is always a choice made by the program you are
running, not by the command prompt.
As you will see, there exists a primitive network protocol—the ancient Telnet protocol—that also sends command
lines simply as text, just as Windows does, so that your program will have to do some kind of escaping if it sends
arguments with spaces or special characters in them. However, if you are using a modern remote protocol like SSH
that lets you send arguments as a list of strings rather than as a single string, then be aware that on Windows systems
all that SSH can do is paste your carefully constructed command line back together and hope that the Windows
command can figure it out.
When sending commands to Windows, you might want to take advantage of the list2cmdline() routine offered
by the Python subprocess module. It takes a list of arguments similar to what you would use for a Unix command
and attempts to paste them together—using double quotes and backslashes when necessary—so that conventional
Windows programs can parse the command line back into exactly the same arguments.





from subprocess import list2cmdline
args = ['rename', 'salary "Smith".xls', 'salary-smith.xls']
print(list2cmdline(args))
rename "salary \"Smith\".xls" salary-smith.xls





Some quick experimentation with your network library and remote-shell protocol of choice should help you
figure out what Windows needs in your situation. For the rest of this chapter, I will make the simplifying assumption
that you are connecting to servers that use a modern Unix-like operating system that can keep discrete command-line
arguments separate without extra quoting.


Things Are Different in a Terminal

You will probably talk to more programs than just a shell over your Python-powered remote connection. You will often
want to watch the incoming data stream for the data and errors printed by the command you are running. Sometimes
you will also want to send data back, either to provide the remote program with input or to respond to questions and
prompts that the program presents.
When performing tasks such as these, at times you may be dismayed to find programs hanging indefinitely
without ever sending the output on which you are waiting. Alternatively, data you send might not seem to be getting
through. To help you through situations like this, a brief discussion of Unix terminals is in order.

Free download pdf