首页 文章

我们如何从python调用bash函数

提问于
浏览
0

假设我有一个bash函数,我将其导入shell .

# cat sample.sh 
function func()
{
    echo "Custom env : $CUSTOM_ENV"
}

现在我在bash shell中获取此脚本: #source sample.sh

然后我定义:

export CUSTOM_ENV="abc"

然后从bash shell调用func(),它显示:

#func
Custom env : abc

现在,如果我从同一个shell调用python脚本,我想从python脚本调用函数func() . 无论如何要实现这一目标?

我尝试了什么:

  • 尝试过os.system('func') - 不起作用

  • 尝试过subprocess.check_output('func',shell = True,env = os.environ.copy()) - 不起作用

任何指导?

3 回答

  • 0

    你需要 export 函数(使用 -f 选项):

    $ 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
    

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

    此外,导出函数是一个仅限bash的东西,所以这只有在从python启动的父shell和shell都是bash时才有效 . 在bash不是默认值的操作系统上(例如最近发布的Ubuntu和Debian),你需要显式运行bash,否则它将无法运行 . 这一切都让它变得相当脆弱,正如@triplee指出的那样,并不是一个好主意 .

  • -1

    在你非常具体的例子中:

    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'")
    

    $ 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
    
  • 0

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

    • 外打击 - >了解 func ,运行python

    • Python,当你调用 os.systemsubprocess.check_output 时运行一个新的bash进程

    • 内部bash - >由Python创建,与外部bash完全不同 .

    你在外部bash中所做的任何事情都是内部bash无法访问的 . 您需要将函数提供给内部bash .

    类似的东西: subprocess.check_call("bash -c '. sample.sh && func'", shell=True)

    这可能不完全正确,但你希望得到这个想法 - 你希望Python创建的内部bash在尝试运行func之前了解该函数 .

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

相关问题