diff -u <(echo "aba"| fold -w1) <(echo "abaa" | fold -w1)
我想从Python代码执行上面的命令。以下是我写的代码。
cmd = "diff -u < (echo 'aba'| fold -w1) < (echo 'abaa' | fold -w1)"
os.system(cmd)
运行上面的代码,我收到sh: 1: Syntax error: "(" unexpected
错误。据我所知,unix os无法解析大括号内的echo命令。
帮我修复此错误。
答案 0 :(得分:2)
该命令在bash
中正常运行,但os.system()
正在/bin/sh
执行命令。您可以查看:
>>> os.system('echo $0')
sh
0
使用/bin/sh
执行命令时失败:
[mhawke@localhost-localdomain ~]$ /bin/sh
sh-4.3$ diff -u <(echo "aba"| fold -w1) <(echo "abaa" | fold -w1)
sh: syntax error near unexpected token `('
sh-4.3$
您可以在bash
中明确地运行命令,如下所示:
>>> os.system("""bash -c 'diff -u <(echo "aba"| fold -w1) <(echo "abaa" | fold -w1)'""")
--- /dev/fd/63 2017-02-26 09:18:14.633395225 +1100
+++ /dev/fd/62 2017-02-26 09:18:14.633395225 +1100
@@ -1,3 +1,4 @@
a
b
a
+a
256
由于您可能对命令的输出感兴趣,因此您通常可以使用subprocess.check_output()
来执行命令并收集其输出。不幸的是,diff
在检测到输入文件中的差异时喜欢返回非零退出代码,因此无法简单地使用check_output
。您可以通过diff
:{/ p>来管道cat
的输出作弊
>>> from subprocess import check_output
>>> output = check_output(['bash', '-c', 'diff -u <(echo "aba"| fold -w1) <(echo "abaa" | fold -w1) | cat'])
>>> print(output)
b'--- /dev/fd/63\t2017-02-26 10:02:56.814044987 +1100\n+++ /dev/fd/62\t2017-02-26 10:02:56.814044987 +1100\n@@ -1,3 +1,4 @@\n a\n b\n a\n+a\n'
>>> print(str(output, encoding='utf8'))
--- /dev/fd/63 2017-02-26 10:02:56.814044987 +1100
+++ /dev/fd/62 2017-02-26 10:02:56.814044987 +1100
@@ -1,3 +1,4 @@
a
b
a
+a
答案 1 :(得分:2)
首先,不鼓励os.system()
支持subprocess.call(cmd, shell=True)
。这是值得了解的,因为subprocess
文档中有很多其他细节,包括shell=True
参数的这种描述(强调添加):
在POSIX上
shell=True
, shell默认为/bin/sh
.... Popen相当于:Popen(['/bin/sh', '-c', args[0], args[1], ...])
所以现在我们知道为什么你的命令不起作用 - 它不是在调用Bash。正如mhawke建议您应该直接调用bash
,但您应该更喜欢subprocess
模块而不是os.system()
:
>>> subprocess.call(['/bin/bash', '-c', 'diff -u <(echo "aba"| fold -w1) <(echo "abaa" | fold -w1)'])
--- /dev/fd/63 2017-02-25 14:32:49.000000000 -0800
+++ /dev/fd/62 2017-02-25 14:32:49.000000000 -0800
@@ -1,3 +1,4 @@
a
b
a
+a
1
请注意,由于我们显式调用Bash shell,因此我们不需要shell=True
,因为我们告诉Bash调用的命令是单个参数,所以我们不需要反复转义他们,例如正如mhawke所做的那样"""
。
一旦您确认此命令有效,您可能希望不再简单地调用call()
到subprocess
其他更易于编写脚本的函数,例如{{3 },它返回一个你可以检查的CompletedProcess
对象。
正如让 - 弗朗索瓦·法布尔建议你可以用subprocess
做更多有力的事情,包括将<()
替换作为单独的进程启动并将它们用于调用diff
,从而避免需要在Python中调用bash
或编写Bash语法。它更冗长,但更具可扩展性和可维护性。
答案 2 :(得分:0)
或者你可以
import subprocess
cmd = """bash -c 'diff -u <(echo "aba"| fold -w1) <(echo "abaa" | fold -w1)'"""
ps = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = ps.communicate()[0]