是否可以使用 python 中 shell 中定义的函数?

Is it possible to use functions defined in the shell from python?

示例:

#!/bin/bash

function my_test(){
    echo this is a test 
}

my_test 1

python -c "from subprocess import check_output; print(check_output('my_test 2', shell=True))"

输出:

this is a test 1
/bin/sh: my_test: command not found
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.5/subprocess.py", line 629, in check_output
    **kwargs).stdout
  File "/usr/lib/python3.5/subprocess.py", line 711, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'my_test 2' returned non-zero exit status 127

您需要导出 shell 函数,因此它将被 child shell 继承。

#!/bin/bash

function my_test(){
    echo this is a test 
}

my_test 1

export -f my_test
python -c "from subprocess import check_output; print(check_output('my_test 2', shell=True))"

您可以使用 os 模块。

import os
os.system("anything what you would like to do in the shell")

os 模块绝对是最简单的方法,不会在 shell 中造成太大麻烦。

导出并非所有 shell 都支持的函数,将代码放入 环境块 。这是 text 的 language-neutral 块,在创建新进程时从父进程复制到子进程。

这是 ShellShock 的基础。

麻烦的是Bash和Python这两种语言是完全不同的,所以用一种语言编写的函数如果不经过翻译就不能直接被另一种语言执行。子进程可以扫描环境块以查找函数,然后将其翻译并编译成自己的语言。很多工作,很容易成为安全问题。

如果您只想执行 Bash->Python->Bash,那么从第一个 Bash 脚本导出函数应该可以,因为它会被复制到每个环境块中。但是,您还在评论中声明您不希望第一个脚本导出它。

那么你可以使用python将函数代码读入文本字符串,然后自己将其放入环境块中(这就是export在 shell 中执行)。使用 os.environ 词典。

实际使用的名称取决于您的 Bash 版本。 ShellShock 漏洞导致了很多变化。最好创建一个测试函数,导出它,然后使用 env 找到它的全名。例如,在我的版本中,一个名为 gash 的简单函数在环境块中显示为 BASH_FUNC_gash%%.

BASH_FUNC_gash%%=() {  echo 'Hollow world'
}

例如:

import os
import subprocess

fun_body="""() {  echo 'Hollow world'
}
"""
os.environ['BASH_FUNC_gash%%'] = fun_body

p1 = subprocess.Popen('./myscript.sh')

p1.wait()

脚本(myscript.sh)包含:

#!/bin/bash
gash

或者您可以再次查看您的设计。混合语言总是有问题的,为什么不全部写在 Python?