为什么这个有效的shell命令会通过子进程在python中抛出错误?

时间:2016-06-16 05:14:02

标签: python bash shell

bash中的行awk -F'[][]' '/dB/ { print $2 }' <(amixer sget Master)返回系统的当前音量(例如“97%”)。

我试图在Python 3中加入它

#!/usr/bin/env python3
import subprocess
command = "awk -F'[][]' '/dB/ { print $2 }' <(amixer sget Master)"
output = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE).stdout.read()

print(output)

然而,shell的输出返回

/bin/sh: 1: Syntax error: "(" unexpected
b''

为什么会失败,如何修复我的代码?

2 个答案:

答案 0 :(得分:3)

因为您使用process substitution形式的bashism,而您的/bin/sh不支持:

<(...)

将此更改为管道可以解决您的问题:

command = "amixer sget Master | awk -F'[][]' '/dB/ { print $2 }'"

替代方案你可以从sh:

开始bash
command = "bash -c 'amixer sget Master | awk -F'\\''[][]'\\'' '\\''/dB/ { print $2 }'\\'''"

但是你很快就会意识到,引用和逃避将成为一场噩梦

答案 1 :(得分:1)

正如已经指出的那样,您使用的语法是bash语法(a.k.a。bashism)。 subprocess.Popen中使用的默认 shell为/bin/sh&amp;它不支持process substitution

您可以通过executable参数指定要使用的shell。

试试这个:

output = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, executable="/bin/bash").stdout.read()