subprocess.call 使用字符串与使用列表 [英] subprocess.call using string vs using list

查看:50
本文介绍了subprocess.call 使用字符串与使用列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 rsync 与 subprocess.call 一起使用.奇怪的是,如果我传递 subprocess.call 一个字符串,它会起作用,但它不适用于列表(ala,Python 的文档).

I am trying to use rsync with subprocess.call. Oddly, it works if I pass subprocess.call a string, but it won't work with a list (ala, Python's doc).

In [23]: sp.call("rsync -av content/ writings_raw/", shell=True)
sending incremental file list

sent 6236 bytes  received 22 bytes  12516.00 bytes/sec
total size is 324710  speedup is 51.89
Out[23]: 0

使用列表调用 sp.call:

In [24]: sp.call(["rsync", "-av", "content/", "writings_raw/"], shell=True)
rsync  version 3.0.9  protocol version 30
Copyright (C) 1996-2011 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
    64-bit files, 64-bit inums, 32-bit timestamps, 64-bit long ints,
    socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace,
    append, ACLs, xattrs, iconv, symtimes

rsync comes with ABSOLUTELY NO WARRANTY.  This is free software, and you
are welcome to redistribute it under certain conditions.  See the GNU
General Public Licence for details.

rsync is a file transfer program capable of efficient remote update
via a fast differencing algorithm.

Usage: rsync [OPTION]... SRC [SRC]... DEST
  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
  or   rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST
  or   rsync [OPTION]... [USER@]HOST:SRC [DEST]
  or   rsync [OPTION]... [USER@]HOST::SRC [DEST]
  or   rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect
to an rsync daemon, and require SRC or DEST to start with a module name.

Options
 -v, --verbose               increase verbosity
 -q, --quiet                 suppress non-error messages
     --no-motd               suppress daemon-mode MOTD (see manpage caveat)
... snipped....
                             repeated: --filter='- .rsync-filter'
     --exclude=PATTERN       exclude files matching PATTERN
     --blocking-io           use blocking I/O for the remote shell
 -4, --ipv4                  prefer IPv4
 -6, --ipv6                  prefer IPv6
     --version               print version number
(-h) --help                  show this help (-h is --help only if used alone)
...snipped ...
rsync error: syntax or usage error (code 1) at main.c(1438) [client=3.0.9]
Out[24]: 1

我使用列表的方式有什么问题?你会怎么修?我需要这个列表,因为我想使用变量.我当然可以使用:

What is wrong with how I use the list? How would you fix it? I need the list, because I would like to use variables. Of course I could use:

  sp.call("rsync -av "+Orig+" "+Dest, shell=True)    

但我想了解 subprocess 如何理解列表与字符串.

But I would like to understand how subprocess understands lists vs. strings.

In [36]: sp.call(['rsync', '-av', ORIG, DEST], shell=False)
sending incremental file list

sent 6253 bytes  received 23 bytes  12552.00 bytes/sec
total size is 324710  speedup is 51.74
Out[36]: 0

设置 shell=False 和一个字符串

In [38]: sp.call("rsync -av"+" "+ORIG+" "+DEST, shell=False)
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-38-0d366d3ef8ce> in <module>()
----> 1 sp.call("rsync -av"+" "+ORIG+" "+DEST, shell=False)

/usr/lib/python2.7/subprocess.pyc in call(*popenargs, **kwargs)
    491     retcode = call(["ls", "-l"])
    492     """
--> 493     return Popen(*popenargs, **kwargs).wait()
    494 
    495 

/usr/lib/python2.7/subprocess.pyc in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags)
    677                             p2cread, p2cwrite,
    678                             c2pread, c2pwrite,
--> 679                             errread, errwrite)
    680 
    681         if mswindows:

/usr/lib/python2.7/subprocess.pyc in _execute_child(self, args, executable, preexec_fn, close_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite)
   1257                     if fd is not None:
   1258                         os.close(fd)
-> 1259                 raise child_exception
   1260 
   1261 

OSError: [Errno 2] No such file or directory

推荐答案

subprocess 处理命令参数的规则实际上有点复杂.

subprocess's rules for handling the command argument are actually a bit complex.

来自文档:

args 应该是程序参数序列或单个字符串.默认情况下,如果 args 是一个序列,则要执行的程序是 args 中的第一项.如果 args 是字符串,则解释是平台相关,如下所述.请参阅 shellexecutable 参数以了解与默认行为的其他差异.除非另有说明,建议将args作为序列传递....如果shell为True,建议传递args 作为字符串而不是序列.

args should be a sequence of program arguments or else a single string. By default, the program to execute is the first item in args if args is a sequence. If args is a string, the interpretation is platform-dependent and described below. See the shell and executable arguments for additional differences from the default behavior. Unless otherwise stated, it is recommended to pass args as a sequence.... If shell is True, it is recommended to pass args as a string rather than as a sequence.

使用 shell=False:

在 Unix 上,如果 args 是一个字符串,则该字符串被解释为要执行的程序的名称或路径.但是,这只有在不向程序传递参数的情况下才能完成.

On Unix, if args is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not passing arguments to the program.

在 Windows 上,如果 args 是一个序列,它将以 在 Windows 上将参数序列转换为字符串.这是因为底层 CreateProcess() 对字符串进行操作.

On Windows, if args is a sequence, it will be converted to a string in a manner described in Converting an argument sequence to a string on Windows. This is because the underlying CreateProcess() operates on strings.

使用 shell=True:

在带有 shell=True 的 Unix 上,shell 默认为 /bin/sh.如果 args 是字符串,则该字符串指定要通过 shell 执行的命令.这意味着字符串的格式必须与在 shell 提示符下键入时完全相同.例如,这包括引用或反斜杠转义其中包含空格的文件名.如果 args 是一个序列,则第一项指定命令字符串,任何附加项都将被视为 shell 本身的附加参数.

On Unix with shell=True, the shell defaults to /bin/sh. If args is a string, the string specifies the command to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt. This includes, for example, quoting or backslash escaping filenames with spaces in them. If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself.

在带有 shell=True 的 Windows 上,COMSPEC 环境变量指定默认 shell.您唯一需要在 Windows 上指定 shell=True 的时间是当您希望执行的命令内置到 shell 中时(例如 dircopy>).您不需要 shell=True 来运行批处理文件或基于控制台的可执行文件.

On Windows with shell=True, the COMSPEC environment variable specifies the default shell. The only time you need to specify shell=True on Windows is when the command you wish to execute is built into the shell (e.g. dir or copy). You do not need shell=True to run a batch file or console-based executable.

(所有重点都是我的)

这篇关于subprocess.call 使用字符串与使用列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆