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

时间:2016-01-01 13:41:24

标签: python shell subprocess

示例:

#!/bin/bash

function my_test(){
    echo this is a test $1
}

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

4 个答案:

答案 0 :(得分:9)

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

#!/bin/sh

function my_test(){
    echo this is a test $1
}

my_test 1

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

答案 1 :(得分:2)

导出所有shell都不支持的函数会将代码放入环境块。这是一个与语言无关的 text 块,在创建新进程时会从父级复制到子级。

这是ShellShock的基础。

麻烦的是Bash和Python这两种语言是完全不同的,因此一个函数编写的函数在没有翻译的情况下不会被另一个直接执行。子进程可以扫描环境块以查找该函数,然后将其翻译并编译为自己的语言。很多工作,很容易成为安全问题。

如果您只想使用Bash-&gt; Python-&gt; Bash,那么从第一个Bash脚本导出该函数应该这样做,因为它将被复制到每个环境块中。但是,您还在评论中说明您不希望第一个脚本导出它。

可以使用python将函数代码读入文本字符串,然后自己将其放入环境块中(这是RewriteRule ^(.*)\.php$ loader.php?page=$1 [NC,L] 在shell中的作用)。使用export字典。

使用的实际名称取决于您的Bash版本。 ShellShock漏洞导致了很多变化。最好创建一个测试函数,导出它,然后使用os.environ查找其全名。例如,在我的版本中,一个名为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

另外,您可以再次查看您的设计。混合语言总是有问题的,为什么不用Python编写全部内容?

答案 2 :(得分:0)

您可以使用os模块。

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

答案 3 :(得分:-2)

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