Bash脚本不会在Python中使用子进程运行

时间:2018-01-07 19:50:42

标签: python bash subprocess

出于某种原因,无论我尝试了多少变化,我似乎都无法执行我写过的bash脚本。

中的命令字在终端中100%正常,但是当我尝试用子进程调用它时,它什么都不返回。

from os import listdir
import subprocess

computer_name = 'homedirectoryname'

moviefolder = '/Users/{}/Documents/Programming/Voicer/Movies'.format(computer_name)

string = 'The lion king'

for i in listdir(moviefolder):
    title = i.split('.')
    formatted_title = title[0].replace(' ', '\ ')

    if string.lower() == title[0].lower():
        command = 'vlc {}/{}.{}'.format(moviefolder, formatted_title, title[1])

        subprocess.call(["/usr/local/bin",'-i','-c', command], stdout=subprocess.PIPE,
                                                        stderr=subprocess.PIPE, shell=True)
    else:
        continue

bash可执行文件如下所示:

#/bin/bash

func() {
    open -a /Applications/VLC.app/Contents/MacOS/VLC $1
}

我哪里出错?

5 个答案:

答案 0 :(得分:2)

您应该直接致电open

import os
import subprocess

computer_name = 'homedirectoryname'

moviefolder = '/Users/{}/Documents/Programming/Voicer/Movies'.format(computer_name)

string = 'The lion king'

for filename in os.listdir(moviefolder):
    title = filename.split('.')

    if string.lower() == title[0].lower():
        subprocess.call(['open', '-a', '/Applications/VLC.app/Contents/MacOS/VLC', os.path.join(moviefolder, filename)])

答案 1 :(得分:1)

就像你在评论中提到的那样,当你从shell中正确捕获错误时,你得到/usr/local/bin: is a directory(并取出错误的shell=True;或者相应地重构命令行以适合这个用法,即传递字符串而不是列表。)

只是拼出这个,你试图用一些选项运行命令/usr/local/bin;但当然,这不是一个有效的命令;所以这失败了。

您似乎想要运行的实际脚本将声明一个函数然后退出,这会导致函数的定义再次丢失,因为运行执行此函数声明的shell的子进程现已终止并释放所有它的资源回到系统。

也许你应该采取更多的步骤来解释你实际想要完成的事情;但实际上,这应该是一个新的,单独的问题。

假设您实际上正在尝试运行vlc,并猜测其他一些事情,也许您真的想要

subprocess.call(['vlc','{}/{}.{}'.format(moviefolder, formatted_title, title[1]),
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)

如果您的PATH是正确的,则不需要明确指定/usr/local/bin/(如果您的PATH错误,请在之前的代码中更正它,而不是硬编码目录你要调用的可执行文件。)

答案 2 :(得分:0)

由于您使用的是shell=True,因此命令必须是字符串:

  

在Unix上,shell = True,shell默认为/ bin / sh。如果args是   string,string指定通过shell执行的命令。   这意味着字符串必须完全按照原样进行格式化   在shell提示符下键入时。这包括,例如,引用或   反斜杠转义文件名,其中包含空格。如果args是   sequence,第一项指定命令字符串,以及任何   其他项目将被视为shell的附加参数   本身。 (docs

答案 3 :(得分:0)

shell=True中使用subprocess.call时,如果命令参数是一个序列,那么序列的第一个元素需要是命令,其余的被视为参数外壳本身。

所以,这应该做:

subprocess.call(["/usr/local/bin/{}".format(command), '-i','-c'], shell=True, ...)

否则,您可以将命令设为字符串。

示例:

In [20]: subprocess.call(["cat spamegg", "-i", "-c"], shell=True)
foobar

答案 4 :(得分:0)

/usr/local/bin是一个目录。您无法像运行命令一样运行目录。

无论如何,在你的命令中任何地方都没有/usr/local/bin没有意义。忽略shell=True,并明确调用vlc

subprocess.call([
  'vlc',
  '{}/{}.{}'.format(moviefolder, formatted_title, title[1])
])