当用分号分隔时,Shlex不能正确地将多个连续的命令传递给子进程。

问题描述 投票:0回答:1

我有两个文件夹。我创建了如下的临时文件

$ touch -t 1604031305 files/tmpfile files2/tmpfile && tree .
.
├── files
│   └── tmpfile
├── files2
│   └── tmpfile
└── test.py

2 directories, 3 files

现在,我可以执行以下命令 find 指挥和 rm 所需的文件。

$ find /path/to/files/ -type f -mtime +3 -exec rm -f {} \; ; find /path/to/files2 -type f -mtime +6 -exec rm -f {} \; ; tree .
.
├── files
├── files2
└── test.py

2 directories, 1 file

我的要求是,我应该能够做到上面的内容。find 命令,通过使用 Subprocess.Popen. 但它抛出了一个错误。

test.py

import shlex
import subprocess

cmd1 = "find /path/to/files/ -type f -mtime +3 -exec rm -f {} \;"
cmd2 = "find /path/to/files2/ -type f -mtime +6 -exec rm -f {} \; "

cmdsplit1 = shlex.split(cmd1)
cmdsplit2 = shlex.split(cmd2)
cmdsplit = cmdsplit1 + cmdsplit2

print(cmdsplit1)
print(cmdsplit2)
print(cmdsplit1 + cmdsplit2)

subprocess.Popen(cmdsplit1) # works on its own
subprocess.Popen(cmdsplit2) # works on its own
subprocess.Popen(cmdsplit) # combination of the two does not work

而我得到的输出是以下内容

$ python3 test.py
# cmdsplit 1 works individually
['find', '/path/to/files/', '-type', 'f', '-mtime', '+3', '-exec', 'rm', '-f', '{}', ';']
# cmdsplit 2 works individually
['find', '/path/to/files2/', '-type', 'f', '-mtime', '+6', '-exec', 'rm', '-f', '{}', ';']
# cmdsplit throws an error
['find', '/path/to/files/', '-type', 'f', '-mtime', '+3', '-exec', 'rm', '-f', '{}', ';', 'find', '/path/to/files2/', '-type', 'f', '-mtime', '+6', '-exec', 'rm', '-f', '{}', ';']
find: paths must precede expression: `find'

我注意到,一个 ; 原命令中没有。所以当我把 cmds 到以下方面:

cmd1 = "find /path/to/files/ -type f -mtime +3 -exec rm -f {} \; ; " # added the extra ; here
cmd2 = "find /path/to/files2/ -type f -mtime +6 -exec rm -f {} \; "

我得到以下输出

$ python3 test.py 
['find', '/path/to/files/', '-type', 'f', '-mtime', '+3', '-exec', 'rm', '-f', '{}', ';', ';']
['find', '/path/to/files2/', '-type', 'f', '-mtime', '+6', '-exec', 'rm', '-f', '{}', ';']
['find', '/path/to/files/', '-type', 'f', '-mtime', '+3', '-exec', 'rm', '-f', '{}', ';', ';', 'find', '/path/to/files2/', '-type', 'f', '-mtime', '+6', '-exec', 'rm', '-f', '{}', ';']
find: paths must precede expression: `;'
find: paths must precede expression: `;'

我不知道自己哪里做错了。

注意:我没有直接把字符串传给子进程的选项。代码库的方式让我无法修改这部分。I 以字符串的形式传递,这 经由 shlex.split() 并传递给Subprocess。我也不能选择将多个 find 命令,也就是说我不能多次调用API,应该一次传完。

python python-3.x subprocess shlex
1个回答
0
投票

谢谢jasonharper。

显然,只有这个方法对我的用例有效。

import shlex
import subprocess

cmd1 = "find /home/kishore/testshlex/files/ -type f -mtime +3 -exec rm -f {} \; ; "
cmd2 = "find /home/kishore/testshlex/files2/ -type f -mtime +6 -exec rm -f {} \; "

cmds = cmd1 + cmd2

sh = "/bin/sh -c"
cmd = shlex.split(sh)
cmd.append(cmds)

subprocess.Popen(cmd)
© www.soinside.com 2019 - 2024. All rights reserved.