我正在尝试执行以下命令(通过python脚本下载Caliber):
sudo -v&& wget -nv -O- https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py | sudo python -c“import sys; main = lambda:sys.stderr.write('Download failed \ n'); exec(sys.stdin.read()); main()”
关于如何PIPE的一些答案,我一直这样做:
import subprocess
from subprocess import Popen, PIPE
wget = subprocess.Popen(["sudo -v wget -nv -O- https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py"], stdout=PIPE)
run = subprocess.Popen(["sudo python -c "import sys; exec(sys.stdin.read()); main()""], stdin=wget.stdout)
我尝试过改变很多东西但是没有用。这里有太多错误。谁能纠正这个?提前谢谢了。
我得到的只是第一个
答案 0 :(得分:1)
如果您有参数,则需要将其分解为列表,例如
wget = subprocess.Popen(["wget -nv -O- https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py"])
(**No such file or directory** error, because it looks for that whole string as a command/file)
需要成为:
subprocess.Popen(['wget', '-nv', '-O-', 'https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py'])
<subprocess.Popen object at 0x10e203950>
您也可以使用shlex.split()
为您分割命令,例如
>>> import shlex
>>> shlex.split('wget -nv -O- https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py')
['wget', '-nv', '-O-', 'https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py']
参考。 https://docs.python.org/2/library/subprocess.html#popen-constructor
你也有"sudo python -c "import sys; exec(sys.stdin.read()); main()""
,我认为这是不可接受的语法,因为你在引号内引用了引号(内部引用了第一个引号),所以请用单引号代替'sudo python -c "import sys; exec(sys.stdin.read()); main()"'
,这样你就不必逃避内部的报价!
答案 1 :(得分:0)
为避免在命令中转义引号,您可以使用三引号:
from subprocess import check_call
check_call(r'''# http://calibre-ebook.com/download_linux
sudo -v &&
wget -nv -O- https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py |
sudo python -c "import sys; main=lambda:sys.stderr.write('Download failed\n'); exec(sys.stdin.read()); main()"
''', shell=True)
shell=True
导致第一个参数被解释为shell命令。
原则上,您可以简化命令:
#!/usr/bin/env python3
import sys
from subprocess import check_call
from urllib.request import urlretrieve
# http://calibre-ebook.com/download_linux
path, _ = urlretrieve('https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py')
check_call(['sudo', sys.executable, path])
但它可能会产生微妙的安全隐患,例如,urlretrieve()
可能会跳过服务器ssl证书验证。