Pythonsubproces.call不按预期工作

2024-09-27 04:29:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我拿不到subprocess.call()正常工作:

>>> from subprocess import call
>>> call(['adduser', '--home=/var/www/myusername/', '--gecos', 'GECOS', '--disabled-login', 'myusername'], shell=True)
adduser: Only one or two names allowed.
1

但是没有外壳=真的:

^{pr2}$

或者直接在shell中:

root@www1:~# adduser --home=/var/www/myusername/ --gecos GECOS --disabled-login myusername
Adding user `myusername' ...
Adding new group `myusername' (1001) ...
Adding new user `myusername' (1001) with group `myusername' ...
Creating home directory `/var/www/myusername/' ...
Copying files from `/etc/skel' ...

我错过了一些真实行为的逻辑。有人能解释一下为什么吗?第一个例子有什么问题?从adduser命令的错误消息来看,参数似乎受到了某种程度的破坏。在

谢谢!在


Tags: fromhomevarwwwloginshellcallsubprocess
3条回答

对此我不是百分之百肯定,但我认为如果您指定Shell=True,您应该将命令行作为单个字符串传递,shell本身会解释:

>>> call('adduser --home=/var/www/myusername/ --gecos GECOS --disabled-login myusername', shell=True)

使用shell=True似乎需要将字符串传递到args中,而不是参数列表中。在

一个简单的测试:

In [4]: subprocess.call(['echo', 'foo', 'bar'], shell=True)

Out[4]: 0

In [5]: subprocess.call('echo foo bar', shell=True)
foo bar
Out[5]: 0

也就是说,echo只有在我使用string而不是list时才得到正确的参数。在

Python 2.7.3版

当您指定shell=True时,您将切换到完全不同的行为。从文件中:

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. That is to say, Popen does the equivalent of:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

所以你在运行相当于

/bin/sh -c "adduser" --home=/var/www/myusername/ --gecos GECOS --disabled-login myusername

您得到的错误消息是当您尝试在没有任何参数的情况下运行adduser,因为所有参数都被传递给sh。在

如果要设置shell=True,则需要这样调用它:

^{pr2}$

或者像这样:

call(['adduser --home=/var/www/myusername/ --gecos GECOS --disabled-login myusername'], shell=True)

但大多数情况下,您只想使用call而不使用shell=True并使用一系列参数。就像你的第二个,工作,例子。在

相关问题 更多 >

    热门问题