python - 如何在 Python 中使用 subprocess 来运行非常复杂的 BASH 命令(有很多重定向和多个部分)?
问题描述
我正在尝试在 Python 中运行以下 BASH 命令,但由于所有重定向(“<”、“>”、“|”)和括号,我遇到了麻烦。
"comm -13 <(sort 9-21-pull/animals.tsv | uniq) <(sort full-data/9-28-full-data/animals.tsv | uniq) > 9-28-pull/animals.tsv"
如何使用子进程在 Python 中运行此 BASH 命令?
解决方案
最小的可能更改是显式使用 bash 。shell=True
uses /bin/sh
,不保证支持进程替换。
从 shell 命令带外传递文件名可以避免安全漏洞:这意味着恶意或意外文件名无法运行任意命令。(同样,prefering sort <"$1"
tosort "$1"
意味着以破折号开头的文件名不能有意外行为)。
subprocess.Popen([
'bash', '-c', 'comm -13 <(sort -u <"$1") <(sort -u <"$2") >"$3"',
'_', # this becomes $0
'9-21-pull/animals.tsv', # this becomes $1
'full-data/9-28-full-data/animals.tsv', # this becomes $2
'9-28-pull/animals.tsv' # this becomes $3
])
现在,如果你根本不想使用 shell 怎么办?我将在uniq
这里留下单独的命令,只是为了展示一个更复杂的案例。
#!/usr/bin/env python3
import subprocess
input1='9-21-pull/animals.tsv' # I'm using a different file when testing, ofc
input2='full-data/9-28-full/animals.tsv'
outfile = '9-28-pull/animals.tsv'
sort_input1 = subprocess.Popen(['sort'],
stdin=open(input1, 'r'),
stdout=subprocess.PIPE)
uniq_input1 = subprocess.Popen(['uniq'],
stdin=sort_input1.stdout,
stdout=subprocess.PIPE)
sort_input2 = subprocess.Popen(['sort'],
stdin=open(input2, 'r'),
stdout=subprocess.PIPE)
uniq_input2 = subprocess.Popen(['uniq'],
stdin=sort_input2.stdout,
stdout=subprocess.PIPE)
comm_proc = subprocess.Popen(['comm', '-13',
f'/dev/fd/{uniq_input1.stdout.fileno()}',
f'/dev/fd/{uniq_input2.stdout.fileno()}'],
stdout=open(outfile, 'w'),
pass_fds=(uniq_input1.stdout.fileno(),
uniq_input2.stdout.fileno()))
sort_input1.stdout.close()
uniq_input1.stdout.close()
sort_input2.stdout.close()
uniq_input2.stdout.close()
comm_proc.wait() # let the pipeline run
推荐阅读
- excel - 如果它包含 Excel 中的填充单元格,则计算列
- mysql - 计算用户使用的数据量(字节)
- sunburst-diagram - 如何使用 R 在旭日形图中自定义戒指尺寸?
- scala - 在 Spark 中,将数据集写入数据库时,保存操作需要一些预先假定的时间
- php - 无法使用 CURL (php) 获取 JSON
- android - getToken() -> BAD_AUTHENTICATION。帐户
- java - 禁用 log4j 2 异常(apache 的异常)
- html - 使用引导程序对齐项目的字段集未正确对齐
- javascript - JavaScript 检查互联网
- android - Android:在 ContentProvider 上下文中找不到处理 Intent 的 Activity