![](/img/trans.png)
[英]run bash script with elevated privileges from subprocess python multithreaded call
[英]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.