Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.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,我有一个由第三方提供的bash脚本,它定义了一组函数。这是一个什么样的模板 $ cat test.sh #!/bin/bash define go() { echo "hello" } 我可以从bash shell中执行以下操作以调用go(): 有没有办法从python脚本访问相同的函数?我尝试了以下方法,但无效: Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) [GCC 4.4.5] on linux2 Type "help",

我有一个由第三方提供的bash脚本,它定义了一组函数。这是一个什么样的模板

$ cat test.sh

#!/bin/bash

define go() {
    echo "hello"
}
我可以从bash shell中执行以下操作以调用go():

有没有办法从python脚本访问相同的函数?我尝试了以下方法,但无效:

Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.call("source test.sh")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/subprocess.py", line 470, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.6/subprocess.py", line 623, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1141, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
>>> 
Python2.6.6(r266:8429220010年9月15日,15:52:39) [GCC 4.4.5]关于linux2 有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。 >>>导入子流程 >>>子流程调用(“source test.sh”) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“/usr/lib/python2.6/subprocess.py”,第470行,在调用中 返回Popen(*popenargs,**kwargs)。等待() 文件“/usr/lib/python2.6/subprocess.py”,第623行,在__ 错误读取,错误写入) 文件“/usr/lib/python2.6/subprocess.py”,第1141行,在执行子进程中 引发子对象异常 OSError:[Errno 2]没有这样的文件或目录 >>>
否,该函数仅在该bash脚本中可用

您可以通过检查参数来调整bash脚本,并在给定特定参数时执行函数

比如说

# $1 is the first argument

case $1 in
 "go" )
       go
       ;;
 "otherfunc" )
       otherfunc
       ;;
 * )
       echo "Unknown function"
       ;;
esac 
然后您可以这样调用函数:

subprocess.call("test.sh otherfunc")

是的,间接地。鉴于此,foo.sh

function go() { 
    echo "hi" 
}
试试这个:

>>> subprocess.Popen(['bash', '-c', '. foo.sh; go'])
输出:

hi

基于@samplebias解决方案,但经过一些对我有效的修改

所以我将其包装到加载bash脚本文件、执行bash函数并返回输出的函数中

def run_bash_function(library_path, function_name, params):
    params = shlex.split('"source %s; %s %s"' % (library_path, function_name, params))
    cmdline = ['bash', '-c'] + params
    p = subprocess.Popen(cmdline,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = p.communicate()
    if p.returncode != 0:
        raise RuntimeError("'%s' failed, error code: '%s', stdout: '%s', stderr: '%s'" % (
            ' '.join(cmdline), p.returncode, stdout.rstrip(), stderr.rstrip()))
    return stdout.strip()  # This is the stdout from the shell command

bash
中有什么函数是在
Python
中不能复制的?如果您编写一个函数来获取任意参数,那么您应该使用
shlex.quote
@donkopotamus,这是正确的,但我认为
shlex.split
在这种情况下可以完成工作,不是吗?i、 e:
shlex.split(“'source%s;%s%s'”%(库路径、函数名、参数))
在您的回答中没有提到
shlex.split
。在任何情况下,
shlex.split
都不会处理引用输入。要点如下。。。如果函数名为
blah;rm-rf/
?(我不建议你测试一下…)@donkopotamus,仍然没有理解你的观点。如果用户决定调用
rm-fr/
而不是调用实际函数,这是他自己的错误。顺便说一句,“blah”不是一个函数名,而是加载函数的库的路径是的,这是一个输入错误。。。我知道
blah
是一个文件名。文件名可以是任何内容。。。如果它们包含对shell有意义的字符,则应在传递给shell之前引用它们。这些字符可以像空格一样简单,也可以像分号一样愚蠢。
def run_bash_function(library_path, function_name, params):
    params = shlex.split('"source %s; %s %s"' % (library_path, function_name, params))
    cmdline = ['bash', '-c'] + params
    p = subprocess.Popen(cmdline,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = p.communicate()
    if p.returncode != 0:
        raise RuntimeError("'%s' failed, error code: '%s', stdout: '%s', stderr: '%s'" % (
            ' '.join(cmdline), p.returncode, stdout.rstrip(), stderr.rstrip()))
    return stdout.strip()  # This is the stdout from the shell command