我可以在Linux的命令行中正常运行:
$ tar c my_dir | md5sum
Run Code Online (Sandbox Code Playgroud)
但是当我尝试用Python调用它时出现错误:
>>> subprocess.Popen(['tar','-c','my_dir','|','md5sum'],shell=True)
<subprocess.Popen object at 0x26c0550>
>>> tar: You must specify one of the `-Acdtrux' or `--test-label' options
Try `tar --help' or `tar --usage' for more information.
Run Code Online (Sandbox Code Playgroud) 所以我写了一个脚本,在命令行上使用nc访问一堆服务器,最初我使用Python的命令模块并调用commands.getoutput(),脚本在大约45秒内运行.由于命令已弃用,我想将所有内容更改为使用子进程模块,但现在脚本需要2m45s才能运行.任何人都知道为什么会这样?
我之前的所作所为:
output = commands.getoutput("echo get file.ext | nc -w 1 server.com port_num")
Run Code Online (Sandbox Code Playgroud)
我现在有
p = Popen('echo get file.ext | nc -w 1 server.com port_num', shell=True, stdout=PIPE)
output = p.communicate()[0]
Run Code Online (Sandbox Code Playgroud)
在此先感谢您的帮助!
我最近遇到了一些有关堆栈溢出的帖子,说子进程比os.system好得多,但是我很难找到确切的优点.
我遇到的一些例子:https: //docs.python.org/3/library/os.html#os.system
"子进程模块提供了更强大的工具来生成新进程并检索其结果;使用该模块比使用此函数更可取."
不知道它在哪些方面更强大,我知道在很多方面使用子进程更容易,但实际上它在某种程度上更强大吗?
另一个例子是:
子进程与系统的优点是它更灵活(你可以得到stdout,stderr,"真正的"状态代码,更好的错误处理等等).
这篇帖子有2600多张选票.再一次找不到更好的错误处理或真实状态代码意味着什么.
该帖子的最高评论是:
无法理解为什么你使用os.system即使是快速/脏/一次性.子进程看起来好多了.
同样,我理解它使一些事情稍微容易些,但我几乎无法理解为什么例如:
subprocess.call("netsh interface set interface \"Wi-Fi\" enable", shell=True)
Run Code Online (Sandbox Code Playgroud)
比任何更好
os.system("netsh interface set interface \"Wi-Fi\" enabled")
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释一些它更好的原因吗?
我正在尝试使用YUIDOC自动生成文档,但我有一个大量使用python的服务器端框架,所以我试图在python脚本中自动化所有内容.我能够让node命令运行正常,但每当我尝试使用npm安装的东西时,python就不高兴了.我的项目使用Buildout而不是virtualenv,但理想情况下我希望能够从一个独立的python文件中运行这些命令.
也许一些代码可以帮助解释我的情况:
import subprocess
subprocess.check_call('node --help')
#SUCCESS
import subprocess
subprocess.check_call('npm --help')
#FAIL
#WindowsError: [Error 2] The system cannot find the file specified
import subprocess
subprocess.check_call('yuidoc --help')
#FAIL
#WindowsError: [Error 2] The system cannot find the file specified
Run Code Online (Sandbox Code Playgroud)
我已经尝试将yuidoc和npm东西所在的文件夹添加到python的sys.path中,但是这不起作用.
我需要弄清楚如何将文件输出写入Python中的压缩文件,类似于下面的双线程:
open ZIPPED, "| gzip -c > zipped.gz";
print ZIPPED "Hello world\n";
Run Code Online (Sandbox Code Playgroud)
在Perl中,这使用Unix gzip将打印到ZIPPED文件句柄的任何内容压缩到文件"zipped.gz".
我知道如何使用"import gzip"在Python中执行此操作,如下所示:
import gzip
zipped = gzip.open("zipped.gz", 'wb')
zipped.write("Hello world\n")
Run Code Online (Sandbox Code Playgroud)
但是,这非常缓慢.根据分析器,使用该方法占用了我运行时间的90%,因为我将200GB的未压缩数据写入各种输出文件.我知道文件系统可能是问题的一部分,但我想通过使用Unix/Linux压缩来排除它.这部分是因为我听说使用同一模块进行解压缩也很慢.
我跑了一下
pip install -r /requirements.txt
Run Code Online (Sandbox Code Playgroud)
如果我的一个软件包出现故障,整个过程就会中止,并且不会安装任何其他软件包.
是否有一个命令,如果发生错误,它将继续安装下一个包?
所以对于我的用例:这是我使用fab文件做的事情:
def _install_requirements():
"""
Installs the required packages from the requirements.txt file using pip.
"""
if not exists(config.SERVER_PROJECT_PATH + '/requirements.txt', use_sudo=True):
print('Could not find requirements')
return
sudo('pip install -r %s/requirements.txt' % SERVER_PROJECT_PATH)
Run Code Online (Sandbox Code Playgroud) 我对如何正确使用Python的子进程模块感到困惑,特别是check_output方法的第一个参数和shell选项.查看下面交互式提示的输出.我将第一个参数作为列表传递,并且根据是否shell=True设置,我得到不同的输出.有人可以解释为什么这是和输出的输出?
>>> import subprocess
>>> subprocess.check_output(["echo", "Hello World!"])
'Hello World!\n'
>>> subprocess.check_output(["echo", "Hello World!"], shell=True)
'\n'
Run Code Online (Sandbox Code Playgroud)
现在,当我将第一个参数作为简单字符串而不是列表传递时,我得到了这个讨厌的堆栈跟踪.为什么会这样?这里发生了什么?
>>> subprocess.check_output("echo Hello World!")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 537, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1228, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Run Code Online (Sandbox Code Playgroud)
但是,当我打开shell = True时,它会完美地运行:
>>> subprocess.check_output("echo Hello World!", shell=True)
'Hello …Run Code Online (Sandbox Code Playgroud) 我想从中获取输出,os.system("nslookup google.com")但0在打印时我总是得到, 。这是为什么,我该如何解决?(Python 3,Mac)
(我查看了如何存储它在 python 中打印到 stdout 的 os.system 的返回值? -但我不明白~我是 python 新手)
我正在研究 Python 是否可以替代 Bash 以用于 shell 脚本编写。我已经看到Python可以使用subprocess.call()或os.system()执行Linux命令。但我在某处读过(忘记了文章的链接),使用这些是一件坏事。这是真的吗?
如果是的话,那为什么这是一件坏事呢?
如果不是,那么可以肯定地说 Python 确实可以替代 Bash 来编写脚本,因为我可以使用这两个函数调用中的任何一个来执行 Linux 命令?
注意:如果我没有记错的话, os.system() 已被弃用,应该使用 subprocess.call() 代替,但这不是问题的要点。
我的 Python 脚本必须运行只能通过控制台访问的二进制文件,所以我使用subprocess.run它,它看起来像这样:
CMD = [
"C:\\Program Files\\Azure DevOps Server 2019\\Tools\\TFSSecurity.exe",
"/gd",
f"[{ARGS.projectName}]\\{ARGS.groupName}",
f"/collection:{ARGS.organization}",
]
DELETE_OUTPUT = subprocess.run(
CMD, check=True, stdout=subprocess.PIPE, shell=True
).stdout.decode("utf-8")
print(f"[DEBUG] DELETE_OUTPUT: {DELETE_OUTPUT}")
Run Code Online (Sandbox Code Playgroud)
它工作正常,但Bandit报告了一些问题:
[B404:blacklist] Consider possible security implications associated with subprocess module.
[B602:subprocess_popen_with_shell_equals_true] subprocess call with shell=True identified, security issue
有没有办法以更安全的方式运行 CLI 以使 Bandit 满意?
python ×10
subprocess ×6
linux ×2
os.system ×2
command ×1
compression ×1
filehandle ×1
gzip ×1
node.js ×1
npm ×1
performance ×1
pipe ×1
popen ×1
python-3.x ×1
scripting ×1
security ×1
shell ×1
yuidoc ×1