Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.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_Shell_Subprocess - Fatal编程技术网

如何从python调用bash函数

如何从python调用bash函数,python,bash,shell,subprocess,Python,Bash,Shell,Subprocess,假设我有一个bash函数,我将其源代码放在一个shell中 # cat sample.sh function func() { echo "Custom env : $CUSTOM_ENV" } 现在,我在bash shell中编写了此脚本的源代码: #源示例.sh 然后我定义: export CUSTOM_ENV="abc" 然后从bash shell调用func(),它显示: #func Custom env : abc 现在,如果我从同一个shell调用python脚本,

假设我有一个bash函数,我将其源代码放在一个shell中

# cat sample.sh 
function func()
{
    echo "Custom env : $CUSTOM_ENV"
}
现在,我在bash shell中编写了此脚本的源代码:
#源示例.sh

然后我定义:

export CUSTOM_ENV="abc"
然后从bash shell调用func(),它显示:

#func
Custom env : abc
现在,如果我从同一个shell调用python脚本, 我想从python脚本中调用函数func()。无论如何,要实现这一点

我尝试的是:

  • 已尝试操作系统('func')-不工作
  • 已尝试子进程。检查输出('func',shell=True,env=os.environ.copy())-不起作用

  • 有什么指导吗?

    您遇到的问题是,涉及到两个独立的bash进程:

    • 外部bash->了解
      func
      ,运行python
    • Python,当您调用
      os.system
      子进程时运行一个新的bash进程
    • 内部bash->由Python创建,与外部bash完全不同
    您在外部bash中所做的任何操作都是内部bash无法访问的。您需要将函数提供给内部bash

    比如:
    subprocess.check_调用(“bash-c'.sample.sh&&func',shell=True)

    这可能并不完全正确,但您希望得到这样的想法——您希望Python创建的内部bash在尝试运行func之前了解函数


    (特别是在这段代码中,第三个shell可能会生成第四个shell-这样更容易,但如果您关心性能,您可能希望稍微调整一下。)

    在您非常具体的示例中:

    import subprocess
    import os
    
    def run_bash(cmd):
        subprocess.Popen(['/bin/bash', '-c', cmd])
    
    #run_bash('ls -ltra')
    #run_bash("date '+%A %W %Y %X'")
    
    os.environ["CUSTOM_ENV"] = "MJ"
    run_bash('./sample.sh')
    
    确保sample.sh通过
    chmod+x sample.sh可执行

    test_bash.py是:

    import subprocess
    
    def run_bash(cmd):
        subprocess.Popen(['/bin/bash', '-c', cmd])
    
    run_bash('ls -ltra')
    run_bash("date '+%A %W %Y %X'")
    


    您需要导出功能(使用
    -f
    选项):

    请注意,
    export
    ing函数(和变量)将函数和变量的副本导出到导出它们的shell的子进程。它们在父(或同级)进程中不可用。此外,在子流程中更改它们不会影响原始副本


    此外,导出函数是bash独有的功能,因此只有当父shell和从python启动的shell都是bash时,这一功能才起作用。在bash不是默认版本的操作系统上(例如,Ubuntu和Debian的最新版本),您需要显式运行bash,否则它将无法工作。这一切使得它相当脆弱,正如@triplee所指出的,这不是一个好主意。

    要么用Python重新编写代码(即使用字符串表示并调用它),要么调用
    bash sample.sh
    。调用bash sample.sh似乎不起作用。尝试过:)请参见(可能重复,尽管细节不同)。这回答了问题,但您可以这样做并不意味着您应该这样做。如果可以避免,请不要使用
    subprocess.Popen
    ,尤其不要以这种方式将悬空的子流程置于未管理状态。另见
    $ python test_bash.py 
    Monday 50 2018 12:47:13 AM
    total 668
    -rw-r--r--. 1 jalal cs-grad   2590 Nov  4 16:46 data_loading.py
    drwxr-xr-x. 8 jalal cs-grad    211 Nov  4 16:46 .git
    drwxr-xr-x. 2 jalal cs-grad     85 Nov  4 22:44 .ipynb_checkpoints
    
    $ function func()
    > {
    >     echo "Custom env : $CUSTOM_ENV"
    > }
    $ export -f func
    $ export CUSTOM_ENV="abc"
    $ python
    Python 2.7.10 (default, Oct  6 2017, 22:29:07) 
    [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os
    >>> os.system('func')
    Custom env : abc
    0