09.11.2016 Views

Foundations of Python Network Programming 978-1-4302-3004-5

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

CHAPTER 16 ■ TELNET AND SSH<br />

As we will see, there does exist a very primitive network protocol—the ancient Telnet protocol—that<br />

also sends command lines simply as text, like Windows does, so that your program will have to do some<br />

kind <strong>of</strong> escaping if it sends arguments with spaces or special characters in them. But if you are using any<br />

sort <strong>of</strong> modern remote protocol like SSH that lets you send arguments as a list <strong>of</strong> strings, rather than as a<br />

single string, then be aware that on Windows systems all that SSH can do is paste your carefully<br />

constructed command line back together and hope that the Windows command can figure it out.<br />

When sending commands to Windows, you might want to take advantage <strong>of</strong> the list2cmdline()<br />

routine <strong>of</strong>fered by the <strong>Python</strong> subprocess module. It takes a list <strong>of</strong> arguments like you would use for a<br />

Unix command, and attempts to paste them together—using double-quotes and backslashes when<br />

necessary—so that “normal” Windows programs will parse the command line back into exactly the same<br />

arguments:<br />

>>> from subprocess import list2cmdline<br />

>>> args = ['rename', 'salary "Smith".xls', 'salary-smith.xls']<br />

>>> print list2cmdline(args)<br />

rename "salary \"Smith\".xls" salary-smith.xls<br />

Some quick experimentation with your network library and remote-shell protocol <strong>of</strong> choice (after<br />

all, the network library might do Windows quoting for you instead <strong>of</strong> making you do it yourself) should<br />

help you figure out what Windows needs in your situation. For the rest <strong>of</strong> this chapter, we will make the<br />

simplifying assumption that you are connecting to servers that use a modern Unix-like operating system<br />

and can keep command-line arguments straight without quoting.<br />

Things Are Different in a Terminal<br />

You will probably talk to more programs than just the shell over your <strong>Python</strong>-powered remote-shell<br />

connection, <strong>of</strong> course. You will <strong>of</strong>ten want to watch the incoming data stream for the information and<br />

errors printed out by the commands you are running. And sometimes you will even want to send data<br />

back, either to provide the remote programs with input, or to respond to questions and prompts that<br />

they present.<br />

When performing tasks like this, you might be surprised to find that programs hang indefinitely<br />

without ever finishing the output that you are waiting on, or that data you send seems to not be getting<br />

through. To help you through situations like this, a brief discussion <strong>of</strong> Unix terminals is in order.<br />

A terminal typically names a device into which a user types text, and on whose screen the<br />

computer's response can be displayed. If a Unix machine has physical serial ports that could possibly<br />

host a physical terminal, then the device directory will contain entries like /dev/ttyS1 with which<br />

programs can send and receive strings to that device. But most terminals these days are, in reality, other<br />

programs: an xterm terminal, or a Gnome or KDE terminal program, or a PuTTY client on a Windows<br />

machine that has connected via a remote-shell protocol <strong>of</strong> the kind we will discuss in this chapter.<br />

But the programs running inside the terminal on your laptop or desktop machine still need to know<br />

that they are talking to a person—they still need to feel like they are talking through the mechanism <strong>of</strong> a<br />

terminal device connected to a display. So the Unix operating system provides a set <strong>of</strong> “pseudoterminal”<br />

devices (which might have less confusingly been named “virtual” terminals) with names like<br />

/dev/tty42. When someone brings up an xterm or connects through SSH, the xterm or SSH daemon<br />

grabs a fresh pseudo-terminal, configures it, and runs the user's shell behind it. The shell examines its<br />

standard input, sees that it is a terminal, and presents a prompt since it believes itself to be talking to a<br />

person.<br />

270

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!