标签: popen

为什么带有shell = True的subprocess.Popen()在Linux与Windows上的工作方式不同?

subprocess.Popen(args, shell=True)用于运行" gcc --version"(仅作为示例)时,在Windows上我们得到:

>>> from subprocess import Popen
>>> Popen(['gcc', '--version'], shell=True)
gcc (GCC) 3.4.5 (mingw-vista special r3) ...
Run Code Online (Sandbox Code Playgroud)

因此,按照我的预期很好地打印出版本.但是在Linux上我们得到了这个:

>>> from subprocess import Popen
>>> Popen(['gcc', '--version'], shell=True)
gcc: no input files
Run Code Online (Sandbox Code Playgroud)

因为gcc还没有收到--version选项.

文档没有明确指出Windows下args应该发生什么,但它确实说,在Unix上,"如果args是一个序列,第一个项目指定命令字符串,任何其他项目将被视为额外的shell参数".恕我直言,Windows方式更好,因为它允许您将Popen(arglist)呼叫视为Popen(arglist, shell=True)一个.

为什么Windows和Linux之间存在差异?

python shell subprocess popen

20
推荐指数
2
解决办法
2万
查看次数

从FILE*指针创建fstream对象

众所周知的创建fstream对象的方法是:

ifstream fobj("myfile.txt");
Run Code Online (Sandbox Code Playgroud)

即.使用文件名.

但我想使用文件描述符创建一个ifstream对象.

原因:我想使用执行命令_popen(). _popen()将输出返回为FILE*.所以有一个FILE*指针涉及但没有文件名.

c++ popen ifstream

20
推荐指数
1
解决办法
1万
查看次数

如何从子进程获取环境?

我想通过python程序调用一个进程,但是,这个进程需要一些由另一个进程设置的特定环境变量.如何获取第一个进程环境变量以将它们传递给第二个?

这就是程序的样子:

import subprocess

subprocess.call(['proc1']) # this set env. variables for proc2
subprocess.call(['proc2']) # this must have env. variables set by proc1 to work
Run Code Online (Sandbox Code Playgroud)

但是进程不共享相同的环境.请注意,这些程序不是我的(第一个是大而丑陋的.bat文件,第二个是专有软件)所以我无法修改它们(好吧,我可以从.bat中提取我需要的所有东西,但它非常简洁).

注意:我使用的是Windows,但我更喜欢跨平台的解决方案(但我的问题不会发生在类似Unix的问题上......)

python windows subprocess environment-variables popen

19
推荐指数
3
解决办法
1万
查看次数

使用Popen.stdin执行多个命令

我想在使用管道从python脚本启动的独立应用程序中执行多个命令.我能够可靠地将命令传递给程序的stdin的唯一方法是使用Popen.communicate,但它会在命令执行后关闭程序.如果我使用Popen.stdin.write而不是命令只执行5次左右,那么它就不可靠.我究竟做错了什么?

详细说明:

我有一个应用程序,它监听stdin的命令并逐行执行它们.我希望能够运行应用程序并根据用户与GUI的交互向其传递各种命令.这是一个简单的测试示例:

import os, string
from subprocess import Popen, PIPE

command = "anApplication" 
process = Popen(command, shell=False, stderr=None, stdin=PIPE)

process.stdin.write("doSomething1\n")
process.stdin.flush()
process.stdin.write("doSomething2\n")
process.stdin.flush()
Run Code Online (Sandbox Code Playgroud)

我希望看到两个命令的结果,但我没有得到任何回应.(如果我多次执行其中一条Popen.write行,它偶尔会有效.)

如果我执行:

process.communicate("doSomething1")
Run Code Online (Sandbox Code Playgroud)

它完美地工作但应用程序终止.

python popen

19
推荐指数
1
解决办法
1万
查看次数

popen()可以像pipe()+ fork()一样制作双向管道吗?

我正在用C++(主要是C)在模拟文件系统上实现管道.它需要在主机shell中运行命令,但在模拟文件系统上执行管道本身.

我可以与实现这一目标pipe(),fork()system()系统调用,但我宁愿使用popen()(它处理创建一条管道,把一个进程,并通过一个命令外壳).这可能是不可能的,因为(我认为)我需要能够从管道的父进程写入,在子进程结束时读取,从子进程写回输出,最后从父进程读取该输出.popen()我的系统上的手册页说明了双向管道,但是我的代码需要在一个只支持单向管道的旧版本的系统上运行.

通过上面的单独调用,我可以打开/关闭管道来实现这一目标.这有可能popen()吗?

对于一个简单的例子,要运行ls -l | grep .txt | grep cmds我需要:

  • 打开管道并ls -l在主机上运行进程; 读回它的输出
  • 将输出管道ls -l传回我的模拟器
  • 打开管道和进程以grep .txt在管道输出上的主机上运行ls -l
  • 将此输出传回模拟器(卡在此处)
  • 打开管道和进程以grep cmds在管道输出上的主机上运行grep .txt
  • 将其输出传回模拟器并打印出来

男人popen

从Mac OS X:

popen()函数通过创建双向管道,分叉和调用shell来"打开"一个过程.由popen() 父进程中先前调用打开的任何流都将在新的子进程中关闭.历史上,popen()使用单向管道实施; 因此,许多实现popen()只允许mode参数指定读或写,而不是两者.因为 popen()现在使用双向管道实现,mode参数可以请求双向数据流.mode参数是一个指向以null结尾的字符串的指针,该字符串必须为'r'表示读取,'w'表示写入,或'r +'表示读写.

c fork pipe popen dup2

19
推荐指数
4
解决办法
1万
查看次数

subprocess.wait()没有等待Popen进程完成(使用线程时)?

subprocess.Popen()我使用线程让我们同时运行它们从我的python脚本生成同一个应用程序的几个实例时,我遇到了一些问题.在每个线程中,我使用popen()调用运行应用程序,然后我等待它通过调用完成wait().问题似乎是wait()-call实际上并不等待进程完成.我只使用一个线程进行实验,并在进程启动时和完成时打印出文本消息.所以线程函数看起来像这样:

def worker():
    while True:
        job = q.get() # q is a global Queue of jobs
        print('Starting process %d' % job['id'])
        proc = subprocess.Popen(job['cmd'], shell=True)
        proc.wait()
        print('Finished process %d' % job['id'])
        job.task_done()
Run Code Online (Sandbox Code Playgroud)

但即使我只使用一个线程,它也会在出现任何"完成进程..."消息之前打印出几个"正在启动进程..."消息.有wait()没有实际上没有等待的情况?我有几个不同的外部应用程序(C++控制台应用程序),它们将同时运行多个实例,对于其中一些我的代码可以工作,但对于其他实例,它不会.外部应用程序是否存在某些问题会以某种方式影响调用wait()?创建线程的代码如下所示:

for i in range(1):
    t = Thread(target=worker)
    t.daemon = True
    t.start()
q.join() # Wait for the queue to empty
Run Code Online (Sandbox Code Playgroud)

更新1:我还应该补充一点,对于某些外部应用程序,我有时会得到proc.returncode-1073471801 的返回码().例如,其中一个外部应用程序将给出前两次Popen调用的返回代码,但不是后两个(当我有四个作业时).

更新2:为了清理,现在我在队列中有四个作业,这是四个不同的测试用例.当我运行我的代码时,对于其中一个外部应用程序,前两个 - Popen调用生成返回代码-1073471801.但是如果我打印出Popen调用的确切命令,并在命令窗口中运行它,它会毫无问题地执行.

解决了! 我设法解决了我遇到的问题.我认为问题在于我缺乏线程编程的经验.我错过了这样一个事实:当我创建了我的第一个工作线程时,他们会一直活着直到python脚本退出.错误的是,每次我将新项目放入队列时,我都会创建更多的工作线程(我会为每个要运行的外部程序批量执行此操作).所以当我进入第四个外部应用程序时,我有四个线程同时运行,即使我只认为我有一个.

python multithreading subprocess popen

19
推荐指数
3
解决办法
5万
查看次数

Python Popen.communicate()内存限制的替代方案?

我有以下大量的Python代码(运行v2.7)导致在MemoryError处理大(几GB)文件时抛出异常:

myProcess = Popen(myCmd, shell=True, stdout=PIPE, stderr=PIPE)
myStdout, myStderr = myProcess.communicate()
sys.stdout.write(myStdout)
if myStderr:
    sys.stderr.write(myStderr)
Run Code Online (Sandbox Code Playgroud)

在阅读文档时Popen.communicate(),似乎有一些缓冲:

注意读取的数据缓冲在内存中,因此如果数据大小很大或不受限制,请不要使用此方法.

有没有办法禁用此缓冲,或强制缓存在进程运行时定期清除?

我应该在Python中使用什么替代方法来运行将千兆字节数据流式传输到的命令stdout

我应该注意,我需要处理输出和错误流.

python memory stream popen

19
推荐指数
2
解决办法
5238
查看次数

将subprocess.Popen输出附加到文件?

我可以成功地将输出重定向到文件,但是这似乎覆盖了文件的现有数据:

import subprocess
outfile = open('test','w') #same with "w" or "a" as opening mode
outfile.write('Hello')
subprocess.Popen('ls',stdout=outfile)
Run Code Online (Sandbox Code Playgroud)

将从'Hello'文件中删除该行.

我想一个解决方法是将输出存储在别处作为字符串或其他东西(它不会太长),并手动附加outfile.write(thestring)- 但我想知道我是否遗漏了模块内的一些方便这一点.

python subprocess popen

19
推荐指数
1
解决办法
2万
查看次数

Python subprocess.Popen()错误(没有这样的文件或目录)

我试图使用Python函数计算文件中的行数.在当前目录中,当os.system("ls")找到文件时,命令subprocess.Popen(["wc -l filename"], stdout=subprocess.PIPE)不起作用.

这是我的代码:

>>> import os
>>> import subprocess
>>> os.system("ls")
sorted_list.dat
0
>>> p = subprocess.Popen(["wc -l sorted_list.dat"], stdout=subprocess.PIPE)File "<stdin>", line 1, in <module>
File "/Users/a200/anaconda/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
File "/Users/a200/anaconda/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
Run Code Online (Sandbox Code Playgroud)

python subprocess system popen

19
推荐指数
2
解决办法
3万
查看次数

使用不同的Python版本调用Python函数最接近的是什么?

说我有两个文件:

# spam.py
import library_Python3_only as l3

def spam(x,y)
    return l3.bar(x).baz(y)
Run Code Online (Sandbox Code Playgroud)

# beans.py
import library_Python2_only as l2

...
Run Code Online (Sandbox Code Playgroud)

现在假设我想spam从内部打电话beans.这不是直接可能的,因为两个文件都依赖于不兼容的Python版本.当然我可以Popen使用不同的python进程,但是如何在没有太多流解析的情况下传入参数并检索结果呢?

python compatibility popen

19
推荐指数
2
解决办法
1336
查看次数