Ответ 1
Да, косвенно. Учитывая это foo.sh:
function go() {
echo "hi"
}
Попробуйте следующее:
>>> subprocess.Popen(['bash', '-c', '. foo.sh; go'])
Вывод:
hi
У меня есть bash script, предоставляемый третьей стороной, которая определяет набор функций. Вот шаблон того, что выглядит как
$ cat test.sh
#!/bin/bash
define go() {
echo "hello"
}
Я могу сделать следующее из оболочки bash для вызова go():
$ source test.sh
$ go
hello
Есть ли способ получить доступ к одной и той же функции из python script? Я попробовал следующее, но это не сработало:
Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.call("source test.sh")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/subprocess.py", line 470, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.6/subprocess.py", line 623, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1141, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
>>>
Да, косвенно. Учитывая это foo.sh:
function go() {
echo "hi"
}
Попробуйте следующее:
>>> subprocess.Popen(['bash', '-c', '. foo.sh; go'])
Вывод:
hi
На основе решения @samplebias, но с некоторой модификацией, которая сработала для меня,
Итак, я завернул его в функцию, которая загружает файл bash script, выполняет функцию bash и возвращает выходные данные
def run_bash_function(library_path, function_name, params):
params = shlex.split('"source %s; %s %s"' % (library_path, function_name, params))
cmdline = ['bash', '-c'] + params
p = subprocess.Popen(cmdline,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
raise RuntimeError("'%s' failed, error code: '%s', stdout: '%s', stderr: '%s'" % (
' '.join(cmdline), p.returncode, stdout.rstrip(), stderr.rstrip()))
return stdout.strip() # This is the stdout from the shell command
Нет, функция доступна только в этом bash script.
Что вы можете сделать, это адаптировать bash script, проверив аргумент и выполнив функции, если задан конкретный аргумент.
Например
# $1 is the first argument
case $1 in
"go" )
go
;;
"otherfunc" )
otherfunc
;;
* )
echo "Unknown function"
;;
esac
Затем вы можете вызвать функцию следующим образом:
subprocess.call("test.sh otherfunc")