Как мы вызываем функции bash из python - PullRequest
0 голосов
/ 10 декабря 2018

Допустим, у меня есть функция bash, которую я отправляю в оболочку.

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

Теперь я создаю этот скрипт в оболочке bash: #source sample.sh

Затем я определяю:

export CUSTOM_ENV="abc"

и затем вызовите func () из оболочки bash, он отображает:

#func
Custom env : abc

Теперь, если я вызываю скрипт python из той же оболочки, я хочу вызвать функцию func() из скрипта Python.В любом случае, чтобы добиться этого?

Что я пробовал:

  1. Tried os.system ('func') - не работает
  2. Tried subprocess.check_output ('func ', shell = True, env = os.environ.copy ()) - Не работает

Любое руководство?

Ответы [ 3 ]

0 голосов
/ 10 декабря 2018

В вашем очень конкретном примере:

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 голосов
/ 10 декабря 2018

Вам необходимо 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

Обратите внимание, что export функция (и переменные) экспортирует копий изфункция и переменная для подпроцессов оболочки, из которой они экспортируются.Они недоступны в родительских (или родственных) процессах.Кроме того, их изменение в подпроцессе не влияет на исходную копию.

Кроме того, экспорт функций выполняется только для bash, поэтому это работает, только если родительская оболочка и оболочка, запущенная из python, являются bash.В ОС, где bash не используется по умолчанию (например, последние выпуски Ubuntu и Debian), вам нужно явно запустить bash, иначе он не будет работать.Все это делает его довольно хрупким, и, как указал @triplee, не очень хорошая идея.

0 голосов
/ 10 декабря 2018

Проблема, с которой вы столкнулись, заключается в том, что задействованы два отдельных процесса bash:

  • Внешний bash -> знает о func, запускает python
  • Python, запускаетновый процесс bash, когда вы вызываете os.system или subprocess.check_output
  • Внутренний bash -> созданный Python, полностью отличающийся от внешнего bash.

Все, что вы сделали ввнешний удар недоступен для внутреннего удара.Вам нужно передать функцию во внутренний bash.

Что-то вроде: subprocess.check_call("bash -c '. sample.sh && func'", shell=True)

Это может быть не совсем верно, но, надеюсь, вы поняли идею - вам нужен внутренний bash, созданныйPython, чтобы узнать о функции перед попыткой запуска func.

(В частности, в этом коде третья оболочка, вероятно, порождает четвертую оболочку - так проще, но если вы заботитесьо производительности, возможно, вы захотите немного подправить.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...