繁体   English   中英

Bash脚本无法在Python中与子进程一起运行

[英]Bash script will not run with subprocess in Python

由于某种原因,无论我尝试了多少变体,我似乎都无法执行我编写的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
}

我哪里出问题了?

您应该直接致电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)])

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

在shell = True的Unix上,shell默认为/ bin / sh。 如果args是字符串,则该字符串指定要通过外壳执行的命令。 这意味着字符串的格式必须与在shell提示符下键入时的格式完全相同。 例如,这包括在文件名中使用引号或反斜杠转义。 如果args是序列,则第一项指定命令字符串,任何其他项都将被视为shell本身的其他参数。 docs

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

只是为了说明这一点,您尝试使用一些选项来运行命令/usr/local/bin 但是,当然,这不是有效的命令; 所以这失败了。

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

也许您不仅应该退后几步,而且还要说明您实际想要完成的工作; 但实际上,这应该是一个新的独立问题。

假设您实际上正在尝试运行vlc ,并且还猜测了其他一些信息,也许您实际上是想要

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

如果您的PATH是正确的,则不需要显式指定/usr/local/bin/ (如果您的PATH是错误的,请在之前的代码中对其进行更正,而不必为您要调用的可执行文件进行硬编码)。

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

因此,应该这样做:

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

否则,可以使命令成为字符串。

例:

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

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

无论如何,根本没有必要在命令中的任何位置都包含/usr/local/bin 省略shell=True ,并显式调用vlc

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM