2016-01-01 3 views
7

例:あなたは、それは子シェルによって継承されますので、シェル関数をエクスポートする必要がありPythonのシェルで定義された関数を使うことはできますか?

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 
+0

'my_test'関数を別のシェルファイルに保存して、別のシェルスクリプト呼び出しで' python -c'を実行してみませんか? – vrs

+1

'/ bin/sh'は' function'キーワードをサポートしていません。あなたのシバンに '#!/ bin/bash'(または他のシェル)を使用してください。 – chepner

+0

なぜ、そのシェルでのみ定義された関数を呼びたいのですか? – nacho4d

答えて

9

#!/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))" 

出力。

#!/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))" 
+0

ありがとう、これは動作しますが、シェルスクリプトに触れることなくPythonから継承する方法があるのだろうかと思っていました。私はこれが正しいとは思わない? – orestisf

+0

この関数を別のスクリプトに入れることはできますか?次に、関数を呼び出す前に 'source scriptname'を使うことができます。 – Barmar

+0

Pythonはシェルスクリプトや関数について何も知らない。コマンドを実行するようにシェルに指示するだけです。関数がシェルの環境になければ、それを実行することはできません。だから、あなたはそれを環境に取り入れるために何かをしなければなりません。 – Barmar

0

osモジュールを使用できます。

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

これは '' python -c ''のインポートos; print(os.system( 'my_test 2')) ''が 'sh:my_test:command not found'を出力するのに役立ちません。 – orestisf

-2

osモジュールは間違いなく最も簡単な方法であり、シェルで大きな問題を引き起こすことはありません。

2

すべてのシェルでサポートされていない関数をエクスポートすると、コードが環境ブロックに配置されます。これは言語に依存しないブロックテキストで、新しいプロセスが作成されたときに親から子にコピーされます。

これはShellShockの基礎となりました。

BashとPythonの2つの言語が全く異なるため、翻訳されていない関数が直接実行することはできません。子プロセスは、環境ブロックをスキャンして関数を探し、それを翻訳してそれ自身の言語にコンパイルすることができます。仕事の多くは、簡単にセキュリティの問題になる可能性があります。

Bash-> Python-> Bashに行きたい場合は、各環境ブロックにコピーされるので、最初のBashスクリプトから関数をエクスポートする必要があります。しかし、コメントでは、最初のスクリプトでエクスポートする必要がないと述べています。

さてあなたは(これはexportは、シェルで何をするかである)自分をブロックし、環境に入れて、その後、テキスト文字列にパイソンを使用した機能コードを読むことができました。 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でたくさん書く必要はないのですか?

関連する問題