Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中运行Bash命令_Python_Bash - Fatal编程技术网

在Python中运行Bash命令

在Python中运行Bash命令,python,bash,Python,Bash,在本地机器上,我运行一个python脚本,其中包含这一行 bashCommand = "cwm --rdf test.rdf --ntriples > test.nt" os.system(bashCommand) 这个很好用 然后我在服务器上运行相同的代码,得到以下错误消息 'import site' failed; use -v for traceback Traceback (most recent call last): File "/usr/bin/cwm", line 48,

在本地机器上,我运行一个python脚本,其中包含这一行

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
os.system(bashCommand)
这个很好用

然后我在服务器上运行相同的代码,得到以下错误消息

'import site' failed; use -v for traceback
Traceback (most recent call last):
File "/usr/bin/cwm", line 48, in <module>
from swap import  diag
ImportError: No module named swap
“导入站点”失败;使用-v进行回溯
回溯(最近一次呼叫最后一次):
文件“/usr/bin/cwm”,第48行,在
从交换导入诊断
ImportError:没有名为swap的模块
因此,我当时所做的是插入一个
print bash命令
,该命令在使用
os.system()

当然,我再次得到错误(由
os.system(bashCommand)
引起),但在该错误之前,它会在终端中打印命令。然后,我只是复制了输出,并复制粘贴到终端,点击回车键,它就工作了


有人知道发生了什么吗?

用subprocess调用它

import subprocess
subprocess.Popen("cwm --rdf test.rdf --ntriples > test.nt")

您收到的错误似乎是因为服务器上没有交换模块,您应该在服务器上安装交换,然后再次运行脚本

不要使用
os.system
。它已被弃用,取而代之的是。来自:“此模块打算替换几个较旧的模块和功能:
os.system
os.spawn

比如你的情况:

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
import subprocess
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()

根据错误,服务器上缺少名为swap的包。这
/usr/bin/cwm
需要它。如果您使用的是Ubuntu/Debian,请使用aptitude安装
Pythonswap

您可以使用bash程序,参数-c用于执行命令:

bashCommand = "cwm --rdf test.rdf --ntriples > test.nt"
output = subprocess.check_output(['bash','-c', bashCommand])

您可以使用
子流程
,但我始终觉得这不是一种“Pythonic”的方式。所以我创建了Sultan(无耻的插件),它使运行命令行函数变得简单


蟒蛇式的方法是使用


subprocess.Popen
获取一个列表,其中第一个元素是要运行的命令,后跟任何命令行参数

例如:

import subprocess

args = ['echo', 'Hello!']
subprocess.Popen(args) // same as running `echo Hello!` on cmd line

args2 = ['echo', '-v', '"Hello Again"']
subprocess.Popen(args2) // same as running 'echo -v "Hello Again!"` on cmd line

也可以使用“os.popen”。 例如:

输出:

total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root   77 ago 13 21:53 test.py

None

为了在一定程度上扩展前面的答案,这里有一些通常被忽略的细节

  • 首选
    subprocess.run()
    over
    subprocess.check\u call()
    和朋友over
    subprocess.call()
    over
    subprocess.Popen()
    over
    os.system()
    over
    os.Popen()
  • 理解并可能使用
    text=True
    ,即
    universal\u newlines=True
  • 理解
    shell=True
    shell=False
    的含义,以及它如何改变报价和shell便利设施的可用性
  • 了解
    sh
    和Bash之间的区别
  • 了解子流程如何与其父流程分离,并且通常不能更改父流程
  • 避免将Python解释器作为Python的子进程运行
下面将更详细地介绍这些主题

首选
subprocess.run()
subprocess.check\u call()
subprocess.Popen()
函数是一个低级的工作,但要正确使用它很困难,最终会复制/粘贴多行代码。。。在标准库中已经方便地作为一组用于各种目的的高级包装函数存在,下面将详细介绍这些函数

这里有一段来自:

调用子流程的推荐方法是对它可以处理的所有用例使用
run()
函数。对于更高级的用例,可以直接使用底层的
Popen
接口

不幸的是,这些包装函数的可用性在不同的Python版本中有所不同

  • subprocess.run()
    正式引入Python 3.5。这意味着要替换以下所有内容
  • Python2.7/3.1中引入了
    subprocess.check_output()
    。它基本上相当于
    subprocess.run(…,check=True,stdout=subprocess.PIPE)。stdout
  • Python2.5中引入了
    子流程.check_call()
    。它基本上相当于
    子流程。run(…,check=True)
  • subprocess.call()
    是在Python 2.4的原始
    subprocess
    模块()中引入的。它基本上相当于
    子流程.run(…).returncode
高级API vs
subprocess.Popen()
重构和扩展的
子流程.run()
比它所取代的旧的遗留函数更具逻辑性和通用性。它返回一个对象,该对象具有各种方法,允许您从已完成的子流程中检索退出状态、标准输出以及一些其他结果和状态指示器

subprocess.run()
是一种方法,如果您只需要一个程序来运行并将控制权返回给Python。对于更复杂的场景(后台进程,可能带有Python父程序的交互式I/O),您仍然需要使用
subprocess.Popen()
,并自己处理所有管道。这需要对所有运动部件有一个相当复杂的理解,不应轻率地进行。较简单的表示(可能仍在运行)流程,在子流程的剩余生命周期中,需要从代码中管理该流程

也许应该强调的是,仅仅
subprocess.Popen()
只会创建一个进程。如果不考虑这一点,则会有一个子流程与Python并行运行,因此是一个“后台”流程。如果它不需要进行输入、输出或与您协调,那么它可以与您的Python程序并行地执行有用的工作

避免
os.system()
os.popen()
自time eternal(好吧,自Python 2.5以来)以来,已包含建议优先选择
子流程
,而不是
os.system()

子程序
total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root   77 ago 13 21:53 test.py

None
normal = subprocess.run([external, arg],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
    check=True,
    text=True)
print(normal.stdout)

convoluted = subprocess.run([external, arg],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
    check=True)
# You have to know (or guess) the encoding
print(convoluted.stdout.decode('utf-8'))
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')

# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    shell=True)

# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
    shell=True)

correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
    # Probably don't forget these, too
    check=True, text=True)

# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
    shell=True,
    # Probably don't forget these, too
    check=True, text=True)
cmd = '''while read -r x;
   do ping -c 3 "$x" | grep 'round-trip min/avg/max'
   done <hosts.txt'''

# Trivial but horrible
results = subprocess.run(
    cmd, shell=True, universal_newlines=True, check=True)
print(results.stdout)

# Reimplement with shell=False
with open('hosts.txt') as hosts:
    for host in hosts:
        host = host.rstrip('\n')  # drop newline
        ping = subprocess.run(
             ['ping', '-c', '3', host],
             text=True,
             stdout=subprocess.PIPE,
             check=True)
        for line in ping.stdout.split('\n'):
             if 'round-trip min/avg/max' in line:
                 print('{}: {}'.format(host, line))
subprocess.run('''
    # This for loop syntax is Bash only
    for((i=1;i<=$#;i++)); do
        # Arrays are Bash-only
        array[i]+=123
    done''',
    shell=True, check=True,
    executable='/bin/bash')
subprocess.run('cd /tmp', shell=True)
subprocess.run('pwd', shell=True)  # Oops, doesn't print /tmp
subprocess.run('cd /tmp; pwd', shell=True)
os.environ['foo'] = 'bar'
subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
#!/usr/bin/env python
import subprocess

with open('test.nt', 'wb', 0) as file:
    subprocess.check_call("cwm --rdf test.rdf --ntriples".split(),
                          stdout=file)
#!/usr/bin/env python
import subprocess

subprocess.check_call("cwm --rdf test.rdf --ntriples > test.nt",
                      shell=True)
#!/usr/bin/env python
import subprocess

subprocess.check_call('program <(command) <(another-command)',
                      shell=True, executable='/bin/bash')