使用带反勾的命令替换subprocess.call()

2024-05-16 18:47:20 发布

您现在位置:Python中文网/ 问答频道 /正文

只要我安装了适当的程序-fortune在Ubuntu 16.04中默认没有安装-fortune我就可以使用下面的命令让我的计算机的语音到文本功能告诉我回去工作,然后读一段{a1}中的励志名言:

spd-say "get back to work and remember `fortune`"

这里我使用带反勾号的命令替换来将调用fortune命令的结果添加到要读取的文本字符串中。在Python中,我可以使用subprocess来执行此操作:

^{pr2}$

但是,用反勾号替换命令在这里似乎不起作用:

subprocess.call(['spd-say', 'get back to work and remember `fortune`'])

在这种情况下,我会听到:“回去工作,记住命运”。我假设这是因为subprocess正在传递一个单引号的字符串,而这种命令替换只适用于双引号字符串。在

我尝试过各种解决方案,包括使用双引号、单引号内的双引号,但我认为它仍然是传递一个单引号内有双引号的字符串,而不是双引号字符串。在

我还尝试将整个命令编写为单个字符串,并使用shlex.split()将其分解:

import shlex
command = 'spd-say "get back to work and remember `fortune`"'
command_args = shlex.split(command)

但这给了我:

['spd-say', 'get back to work and remember `fortune`']

再说一遍,不要用双引号。在

是否有任何方法可以强制将一个参数用双引号括起来(如果这确实是个问题),或者以上面描述的使用subprocess.call()的方式将fortune命令的输出通过管道传递到spd-say?在


Tags: andto字符串命令getbackworksay
1条回答
网友
1楼 · 发布于 2024-05-16 18:47:20

扩展命令替换是一个shell操作。如果没有shell=True,则没有shell参与subprocess操作。一般来说,这是非常理想的行为:如果您将文件名作为输入传递,您不希望包含$(rm -rf $HOME)(是的,在典型的UNIX系统中,所有这些字符在文件名中都是合法的)的文件名会导致内容被删除。在

但是,如果您确定要进行命令替换,那么就需要在shell求值的地方:

subprocess.call('spd-say "get back to work and remember $(fortune)"', shell=True)

…这相当于不带shell=True

^{pr2}$

顺便说一句,如果传递带有shell=True的数组,则只有第一个参数被解析为脚本(因此执行了命令替换和类似的扩展);其他参数是可以由脚本本身解释的文本参数:

subprocess.call(
  ['spd-say "$1 $(fortune)"',                     # this is a script
   "_",                                           # this is a literal for $0 in the script
   "get back to work, don't $(rm), and remember"  # this is a literal for $1 in the script
  ], shell=True)

此处不执行$(rm),因为只有第一个列表元素('spd-say "$1 $(fortune)"')中的内容被视为脚本文本。在

相关问题 更多 >