如何使用python变量作为参数从python脚本调用bash脚本并设置pid

如何使用python变量作为参数从python脚本调用bash脚本并设置pid,python,bash,Python,Bash,我有以下代码: port_temp = 8080 process_getpodsnamesipport = subprocess.call(['bash','getpodsnamesipport.sh', port_temp],preexec_fn=os.setsid) 我想做一些类似的事情: os.killpg(os.getpgid(process_getpodsnamesipport.pid), signal.SIGKILL) 终止进程,但只能使用subprocess.Popen os

我有以下代码:

port_temp = 8080
process_getpodsnamesipport = subprocess.call(['bash','getpodsnamesipport.sh', port_temp],preexec_fn=os.setsid)
我想做一些类似的事情:

os.killpg(os.getpgid(process_getpodsnamesipport.pid), signal.SIGKILL)

终止进程,但只能使用subprocess.Popen

os.killpg(os.getpgid(process_getpodsnamesipport.pid), signal.SIGKILL)
AttributeError: 'int' object has no attribute 'pid'

我会使用Popen并尝试以下内容:

import subprocess
import os
import signal
import pipes

port_temp = 8080
cmd = ["./getpodsnamesipport.sh", str(port_temp)]

# to address Charles Duffy's suggestion for displaying the command
print(' '.join([pipes.quote(s) for s in cmd]))

process_getpodsnamesipport = subprocess.Popen(cmd,
                                              stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE,
                                              shell=False,
                                              preexec_fn=os.setsid)
std_out, std_err = process_getpodsnamesipport.communicate()
这对我很有用:

process_getpodsnamesipport = subprocess.Popen(['./getpodsnamesipport.sh', str(port_temp)],preexec_fn=os.setsid)
    //something something
    os.killpg(os.getpgid(process_getpodsnamesipport.pid), signal.SIGKILL)

call
返回时,进程将已终止。如果您希望在Python脚本继续处理时运行并行进程,
Popen
正是正确的选择。@tripleee是的,这就是我想要的。但是在这种情况下,如何使用
Popen
?与参数
port_temp
Popen
一样,它接受与其他
子流程
函数完全相同的第一个参数。我相信您需要
str(port_temp)
来调用
子进程。顺便说一句,
bash somescript.sh
通常被认为是不好的形式。让脚本本身在shebang行中识别其解释器,然后您可以运行
['./somescript',arg']
,如果脚本所需的解释器在将来发生更改,您不会突然产生错误。(
.sh
文件扩展名格式不好——它们意味着
sh
可用作解释器,这对于为
bash
编写的任何东西都是不正确的。)@Rachelia,…正如tripleee所说,
p=subprocess.Popen(['./getpodsnamesipport.sh',str port_temp)]
将创建一个后台进程。(将某些内容放在后台,但仍然试图捕获输出是另一种更复杂的事情。)
split()。底层操作系统接口(在UNIX系列操作系统上)是单个字符串的列表,每个参数一个;编写代码以反映该接口意味着更少的活动部件,从而减少出错。顺便说一句,
communicate()
在子进程关闭其stdout和stderr之前不会返回,通常在退出后才会返回,因此我看不出
killpg()
有什么好处在打电话给Popen时,这只是为了清楚起见。我从中提取的代码需要显示在命令行上运行的命令,但我同意如果传递的参数带有空格,这将导致中断。Re:clarity,我建议从列表开始,然后使用
'.join([pipes.quote代表arg_列表中的s])
创建字符串版本(如果需要)。这样,对于任何可能的参数列表,包括元素包含文本空白的参数列表,都会得到一个正确的字符串(计算结果与任何POSIX shell中有问题的命令相同)。(在Python3中,用
shlex.quote()
替换
pipes.quote()
)。为什么不使用?真正需要杀死整个流程组是很少见的,而不是编写子流程,让信号处理程序做正确的事情(或者
exec
您需要调用的代码,因此它根本不被委托给子流程)。