问题
Example:
#!/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))"
output:
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
回答1:
You need to export the shell function, so it will be inherited by child shells.
#!/bin/bash
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))"
回答2:
Exporting a function, which is not supported by all shells, places the code into the environment block. This is a language-neutral block of text, which is copied from parent to child when a new process is created.
This was the basis of ShellShock.
The trouble is that the two languages Bash and Python are totally different, so a function written in one will not be directly executable by the other without translation. The child process could scan the environment block looking for the function, then translate and compile it into its own language. A lot of work, and could easily be a security issue.
If you just want to go Bash->Python->Bash, then exporting the function from first Bash script should do it, because it will be copied into each environment block. However you also state in a comment that you don't want the first script to export it.
Well you could read the function code using python into a text string, then put it into the environment block yourself (this is what export
does in the shell). Use the os.environ
dictionary.
The actual name used is dependant on your version of Bash. The ShellShock vulnerability resulted in a lot of changes. Best create a test function, export it, then use env
to find its full name. For example on my version a simple function called gash
appears in the environment block as BASH_FUNC_gash%%
.
BASH_FUNC_gash%%=() { echo 'Hollow world'
}
For example:
import os
import subprocess
fun_body="""() { echo 'Hollow world'
}
"""
os.environ['BASH_FUNC_gash%%'] = fun_body
p1 = subprocess.Popen('./myscript.sh')
p1.wait()
The script (myscript.sh
) contains:
#!/bin/bash
gash
Alternatively you could look at your design again. Mixing languages is always problematic, why not write the whole lot in Python?
回答3:
You can use the os module.
import os
os.system("anything what you would like to do in the shell")
回答4:
The os module is definitely the easiest way and does not cause much trouble in a shell.
来源:https://stackoverflow.com/questions/34556609/is-it-possible-to-use-functions-defined-in-the-shell-from-python