我想以下列方式使用子进程模块:
stdout(或者stderr,或者两者一起或分别捕获)我已经用Popen创建了进程,但是如果我使用communication(),那么一旦进程终止,数据就会立刻出现在我面前.
如果我创建一个单独的线程,做了阻塞readline()的myprocess.stdout(使用stdout = subprocess.PIPE)我不明白这种方法的任何行或者,直到进程终止.(无论我设置为bufsize)
有没有办法解决这个不可怕的问题,并且在多个平台上运行良好?
我有一些自定义命令.
# works
subprocess.Popen(['python'], stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)
但是,如果我有自己的系统命令deactivate,我会得到那个错误
Traceback (most recent call last):
File "runner2.py", line 21, in <module>
main()
File "runner2.py", line 18, in main
subprocess.Popen(['deactivate',], stdout=subprocess.PIPE)
File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Run Code Online (Sandbox Code Playgroud)
更别说我需要在我的沙箱virtualenv下执行此操作.
我正在使用这个subprocess.Popen调用,在另一个问题中,我发现我误解了Python是如何为命令行生成参数的.
我的问题
有没有办法找出实际的命令行是什么?
示例代码: -
proc = subprocess.popen(....)
print "the commandline is %s" % proc.getCommandLine()
Run Code Online (Sandbox Code Playgroud)
你会怎么写getCommandLine?
我想从执行Test_Pipe.py输出,我尝试在Linux上使用代码,但它没有用.
Test_Pipe.py
import time
while True :
print "Someting ..."
time.sleep(.1)
Run Code Online (Sandbox Code Playgroud)
Caller.py
import subprocess as subp
import time
proc = subp.Popen(["python", "Test_Pipe.py"], stdout=subp.PIPE, stdin=subp.PIPE)
while True :
data = proc.stdout.readline() #block / wait
print data
time.sleep(.1)
Run Code Online (Sandbox Code Playgroud)
该行proc.stdout.readline()被阻止,因此没有数据打印出来.
我正在使用Popen调用一个shell脚本,该脚本不断将其stdout和stderr写入日志文件.有没有办法连续同时输出日志文件(到屏幕),或者让shell脚本同时写入日志文件和标准输出?
我基本上想在Python中做这样的事情:
cat file 2>&1 | tee -a logfile #"cat file" will be replaced with some script
Run Code Online (Sandbox Code Playgroud)
再次,这将stderr/stdout连接到tee,将它写入stdout和我的日志文件.
我知道如何在Python中将stdout和stderr写入日志文件.我被困在哪里是如何将这些复制回屏幕:
subprocess.Popen("cat file", shell=True, stdout=logfile, stderr=logfile)
Run Code Online (Sandbox Code Playgroud)
当然我可以做这样的事情,但有没有办法在没有tee和shell文件描述符重定向的情况下做到这一点?:
subprocess.Popen("cat file 2>&1 | tee -a logfile", shell=True)
Run Code Online (Sandbox Code Playgroud) 我有一个.sh脚本,我打电话给source the_script.sh.定期打电话很好.但是,我试图通过我的python脚本调用它subprocess.Popen.
从Popen调用它,我在以下两个场景调用中遇到以下错误:
foo = subprocess.Popen("source the_script.sh")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 672, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1213, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
>>> foo = subprocess.Popen("source the_script.sh", shell = True)
>>> /bin/sh: source: not found
Run Code Online (Sandbox Code Playgroud)
是什么赋予了?为什么我不能从Popen中调用"source",当我可以在python之外?
我正在研究一个漂亮的小功能:
def startProcess(name, path):
"""
Starts a process in the background and writes a PID file
returns integer: pid
"""
# Check if the process is already running
status, pid = processStatus(name)
if status == RUNNING:
raise AlreadyStartedError(pid)
# Start process
process = subprocess.Popen(path + ' > /dev/null 2> /dev/null &', shell=True)
# Write PID file
pidfilename = os.path.join(PIDPATH, name + '.pid')
pidfile = open(pidfilename, 'w')
pidfile.write(str(process.pid))
pidfile.close()
return process.pid
Run Code Online (Sandbox Code Playgroud)
问题是这process.pid不是正确的PID.它似乎总是比正确的PID低1.例如,它表示该过程始于31729,但ps表示它正在31730运行.每次我尝试将其关闭1.我猜它返回的PID是当前进程的PID ,而不是已启动的PID ,并且新进程获得的"下一个"pid高出1.如果是这种情况,我不能仅仅依靠返回,process.pid …
非常具体的问题(我希望):以下三个代码之间有什么区别?
(我希望它只是第一个不等待子进程完成,而第二个和第三个进行.但我需要确定这是唯一的区别......)
我也欢迎其他评论/建议(虽然我已经很清楚shell=True危险和跨平台限制)
请注意,我已经阅读过Python子进程交互,为什么我的进程可以使用Popen.communicate,但不能使用Popen.stdout.read()?并且我不希望/之后需要与程序交互.
另请注意,我已经阅读了Python Popen.communicate()内存限制的替代品?但是我没有真正得到它......
最后,请注意我知道当一个缓冲区使用一种方法填充一个输出时存在死锁的风险,但我在互联网上寻找清晰的解释时迷路了......
第一个代码:
from subprocess import Popen, PIPE
def exe_f(command='ls -l', shell=True):
"""Function to execute a command and return stuff"""
process = Popen(command, shell=shell, stdout=PIPE, stderr=PIPE)
stdout = process.stdout.read()
stderr = process.stderr.read()
return process, stderr, stdout
Run Code Online (Sandbox Code Playgroud)
第二个代码:
from subprocess import Popen, PIPE
from subprocess import communicate
def exe_f(command='ls -l', shell=True):
"""Function to execute a command and return stuff"""
process = Popen(command, shell=shell, stdout=PIPE, stderr=PIPE)
(stdout, stderr) …Run Code Online (Sandbox Code Playgroud) 我正在尝试从python启动一个完全独立的进程.我不能使用像os.startfile这样简单的东西,因为我需要传递参数.目前我正在使用subprocess.popen,它让我90%的方式.
args = ["some_exe.exe", "some_arg", "another_arg"]
subprocess.Popen(args, creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)
使用带有分离创建标志和std*管道的popen会启动一个新进程,该进程在父进程终止后继续存在.这一切都很好.问题是新的'子'进程仍然保留了父进程的幻象句柄.因此,如果我尝试卸载父exe(我的python脚本通过pyinstaller捆绑到exe),msiexec抱怨父exe仍在使用中.
因此,目标是生成一个完全独立的进程来运行"some_exe.exe",它没有任何句柄回原始进程.
注意:这适用于Windows XP及更高版本.我正在开发Win7.
我正在使用Python 2.6中的GUI前端,通常它非常简单:您使用subprocess.call()或subprocess.Popen()发出命令并等待它完成或对错误做出反应.如果您的程序停止并等待用户交互,您会怎么做?例如,程序可能会停止并询问用户是否有ID和密码或如何处理错误?
c:\> parrot
Military Macaw - OK
Sun Conure - OK
African Grey - OK
Norwegian Blue - Customer complaint!
(r) he's Resting, (h) [Hit cage] he moved, (p) he's Pining for the fjords
Run Code Online (Sandbox Code Playgroud)
到目前为止,我所阅读的所有内容都告诉您如何在程序完成后才读取程序的所有输出,而不是在程序运行时如何处理输出.我无法安装新模块(这是一个LiveCD),我将不止一次处理用户输入.
popen ×10
python ×10
subprocess ×8
command-line ×2
communicate ×1
frontend ×1
linux ×1
stdout ×1
unix ×1
wait ×1