nested escape chars in a shell command

jepler at unpythonic.net jepler at unpythonic.net
Thu Oct 20 20:34:02 EDT 2005


I think you're mistaken about how 'sh -c' works.  The next argument after "-c" is
the script, and following arguments are the positional arguments. (what, you've
never used -c in conjunction with positional arguments?  me either!)

Example:
------------------------------------------------------------------------
$ /bin/sh -c 'echo $#' a b c

# i.e., a blank line
$ /bin/sh -c 'echo $# 0=$0 1=$1 2=$2' a b c
2 0=a 1=b 2=c
# i.e., a, b, c went to positional arguments
------------------------------------------------------------------------

Additionally, unless pexpect.spawn behaves differently than os.spawnv,
"-c" is actually going to /bin/sh's argv[0], and you end up trying to execute
/usr/bin/ssh as a shell script, which is probably not what you want!

------------------------------------------------------------------------
def shellquote(arg):
    # shell quoting technique I first read about on the 'git' development list
    # Everything is safely quoted inside a ''-quoted string, except a ' itself,
    # which can be written as '\'' (a backslash-escaped ' outside of the ''-quoted
    # string)
    return "'" + arg.replace("'", "'\\''") + "'"

def shellquotelist(args):
    return " ".join([shellquote(arg) for arg in args])

# XXX: you may wish to assemle 'command' using shellquotelist too
command1 = shellquotelist(['/bin/sh', '-c','/usr/bin/ssh','-t','-o',
			'StrictHostKeyChecking no',host,command])
command2 = shellquotelist(['awk','{print %s:$0}'%host])

child = \
    pexpect.spawn('/bin/sh',
	args=['/bin/sh', '-c', command1 + "|" + command2],
	timeout=30)
------------------------------------------------------------------------

Finally, in your case the use of awk would seem to be gratuitous.  Instead,
prepend the hostname to each line when you read the lines in.  (this could easy
or hard depending on the structure of the code where you read the output
generated by child---if you do it with readline() or by iterating over the file,
it is probably easy)

Jeff
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20051020/61a5901e/attachment.sig>


More information about the Python-list mailing list