Python2.7 -执行带有子进程的shell命令,并为另一个使用输出



我试图在pod中执行一些命令,但它不起作用。你有什么建议吗?

import subprocess
p = subprocess.Popen('kubectl get pods -o=custom-columns=NAME:.metadata.name | grep -i nottepod' , shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
print line,
#Here the line = exact name of the pod. After here not working. it's not login to the pods
p2 = subprocess.Popen("kubectl exec -it' +$(line)+ '-- bash'" , shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
p3 = subprocess.Popen("ls -lrth" , shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line2 in p3.stdout.readlines():
print line2,
retval = p3.wait()

我希望在使用p2步骤进入pod后运行几个命令。

我真正尝试的是,首先,获得pod名称(p1),使用exec命令(p2)登录到pod,这就是为什么我需要p1输出在其中使用。在我登录到pod后,我还需要运行一些命令(p3..等),这是我的主要目的。下面你可以看到当我手动运行它们时发生了什么。

[abc@master ~]$ kubectl get pods -o=custom-columns=NAME:.metadata.name | grep -i nottepod

nottepod-xyz

(abc@master ~)

美元[abc@master ~]$kubectl exec -it nottepod-xyz—bash

默认容器"notte"Out of: note, key

[root@master - note]# ls -lrth

[root@master - note]# ls -lrth

总216

drwxr-xr-x 2 root root 6 Jul 6 2022 Cache

-rwxr-xr-x 3 1037 users 111 Dec 26 16:51 start.sh

-rwxr-xr-x 3 1037 users 291 Dec 26 16:51 rataten.sh

如果您只是想插入名为line的Python变量,那么您可能需要

p2 = subprocess.check_output(
["kubectl", "exec", "-it", line, "--",
"bash", "-c", "couple of commands; more commands"])

注意,这也避免了shell=True的开销和安全隐患

一般情况下,尽量避免使用Popen

如果您真的希望exec bash能够交互地接受命令,那么您确实需要Popen,并且需要将这些命令作为标准输入提交到交互式shell。但如果可以的话,最好避免这种情况。

这里是一个重构,在所有地方使用check_output,避免使用shell=True

import subprocess
pods = subprocess.check_output(['kubectl', 'get', 'pods', '-o=custom-columns=NAME:.metadata.name'])
nottepod = [pod for pod in pods.splitlines() if 'nottepod' in pod.lower()]
assert len(nottepod) == 1
nottepod = pod[0]
print(nottepod,)
lsout = subprocess.check_output(
['kubectl', 'exec', '-it', nottepod, '--',
'bash', '-c', 'ls -lrth'])
for line in lsout.splitlines():
print(line,)

将输出分成几行,然后单独打印它们显然是愚蠢的,但我想您最终可能希望对每个输出行做一些更有用的事情。如果没有,简单的print(lsout,)在一个简单的。


(以下是我在你澄清你的问题之前的部分原始回答。我把它移到了这里,以防将来有访问者遇到不同的问题。

表达式$(line)是错误的,但我们无法真正猜出你希望它是什么意思。

如果line是您想要作为命令替换运行的命令,那么语法是正确的,但是您可能想要删除它周围的单引号和加号,并且可能要添加双引号。(这似乎难以置信,但我还是要提一下。)

# XXX FIXME: implausible but still possible
p2 = subprocess.check_output(
'kubectl exec -it "$(line)" -- bash',
shell=True)

如果您想使用Python变量line的值作为要运行的命令,那就是

# XXX FIXME: also implausible but still possible
p2 = subprocess.check_output(
'kubectl exec -it "$(' + shlex.quote(line) + ')" -- bash',
shell=True)

不清楚要如何处理子流程的输出。如果你不关心输出,你可能想使用check_call,但如果你不希望它们显示给用户,你可能想使用stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL

相关内容

最新更新