当用分号分隔时,Shlex 不会将多个连续的命令正确传递给子进程
Shlex does not pass multiple consecutive commands properly to subprocess when separated by semicolon
我有两个文件夹。我创建了如下临时文件
$ 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
我的要求是我应该能够使用 Subprocess.Popen
执行上述 find
命令。但它会引发错误。
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: `;'
我不确定哪里出错了。
注意:我没有将字符串直接传递给子进程的选项。代码库的方式使我无法修改该部分。我有将其作为字符串传递,将由shlex.split()
解析并传递给子进程。我也没有一个一个地传递多个 find
命令的选项,这意味着我不能多次调用 API,我应该一次传递它。
感谢 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)
我有两个文件夹。我创建了如下临时文件
$ 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
我的要求是我应该能够使用 Subprocess.Popen
执行上述 find
命令。但它会引发错误。
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: `;'
我不确定哪里出错了。
注意:我没有将字符串直接传递给子进程的选项。代码库的方式使我无法修改该部分。我有将其作为字符串传递,将由shlex.split()
解析并传递给子进程。我也没有一个一个地传递多个 find
命令的选项,这意味着我不能多次调用 API,我应该一次传递它。
感谢 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)