41

subprocess.call で rsync を使用しようとしています。奇妙なことに、subprocess.call に文字列を渡すと機能しますが、リスト (ala、Python のドキュメント) では機能しません。

文字列で sp.call を呼び出す:

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

リストの使用方法の何が問題になっていますか? どのように修正しますか?変数を使いたいので、リストが必要です。もちろん、私は使用できます:

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

subprocessしかし、リストと文字列をどのように理解するかを理解したいと思います。

shell=False とリストの設定:

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
4

1 に答える 1

55

subprocessコマンド引数を処理するためののルールは、実際には少し複雑です。

ドキュメントから:

argsプログラム引数のシーケンスであるか、単一の文字列である必要があります。デフォルトでは、実行するプログラムはargsifargsがシーケンスの最初の項目です。が文字列の場合args、解釈はプラットフォームに依存し、以下で説明します。デフォルトの動作とのその他の違いについては、shellおよび引数を参照してください。特に明記されていない限り、シーケンスとして渡すことをお勧めします。trueの場合、シーケンスではなく文字列として渡すことをお勧めします。executableargsshellargs

shell=False

Unixでは、argsが文字列の場合、その文字列は実行するプログラムの名前またはパスとして解釈されます。ただし、これは、プログラムに引数を渡さない場合にのみ実行できます。

Windowsでは、がシーケンスの場合、Windowsでの引数シーケンスの文字列への変換argsで説明されている方法で文字列に変換されます。これは、基になるものが文字列を操作するためです。CreateProcess()

shell=True

Unixshell=Trueの場合、シェルのデフォルトは/bin/sh。です。argsが文字列の場合、文字列はシェルを介して実行するコマンドを指定します。つまり、文字列は、シェルプロンプトで入力したときとまったく同じようにフォーマットする必要があります。これには、たとえば、スペースを含むファイル名を引用符または円記号でエスケープすることが含まれます。argsがシーケンスの場合、最初の項目はコマンド文字列を指定し、追加の項目はシェル自体への追加の引数として扱われます。

Windowsのshell=True場合、COMSPEC環境変数はデフォルトのシェルを指定します。Windowsで指定する必要があるshell=Trueのは、実行するコマンドがシェルに組み込まれているときだけです(例dirまたはcopy)。shell=Trueバッチファイルやコンソールベースの実行可能ファイルを実行する必要はありません。

(すべて強調鉱山)

于 2013-02-27T10:40:40.943 に答える