2016-10-19 1 views
0

私はここで私の脳を壊して、shell = trueを使わずにPythonで単純な関数を実行しようとしています。私はLinux上でPython 2.7を使用しています。Pythonのサブプロセスヘルプ - shell = trueを使用できない

私はこれを行うために複数の方法を試しました。

import subprocess as s 

var1 = s.call("echo $HOME", shell=True) 

import subprocess as s 

var1 = s.check_output("echo $HOME", shell=True) 

両方はそれが必要のような... /home/myhost

を返すが、私が試した他のすべてが失敗します。私はそうのようなシェル= trueを使用している場合は正常に動作します。ほとんどの場合、コマンドの代わりに変数を文字列として渡しているようです。

import subprocess as s 

var1 = s.Popen(['echo', '$HOME'], stdout=s.PIPE) 

print var1 

戻り

[email protected]:~/Desktop$ python home_test.py 
<subprocess.Popen object at 0x7f297ebcbf90> 
[email protected]:~/Desktop$echo: write error: Broken pipe 
:私はこれを試み

[email protected]:~/Desktop$ python home_test.py 
    File "home_test.py", line 42, in <module> 
    main() 
    File "home_test.py", line 11, in main 
    my_test() 
    File "home_test.py", line 16, in check_auth 
    var1 = s.check_output("echo $HOME") 
    File "/usr/lib/python2.7/subprocess.py", line 567, in check_output 
    process = Popen(stdout=PIPE, *popenargs, **kwargs) 
    File "/usr/lib/python2.7/subprocess.py", line 711, in __init__ 
    errread, errwrite) 
    File "/usr/lib/python2.7/subprocess.py", line 1343, in _execute_child 
    raise child_exception 
OSError: [Errno 2] No such file or directory 

import subprocess as s 

print var1 

戻り値:

これらは私が様々な方法で受信された結果であります

次に、この:

import subprocess as s 

cmd1 = '$HOME' 
var1 = s.Popen(['/bin/echo', cmd1], stdout=s.PIPE) 

print var1 

戻り

('$Home\n', None) 

[email protected]:~/Desktop$ python home_test.py 
('Home\n', None) 

は、いくつかのドキュメントが見つかっこの

import subprocess as s 

cmd1 = 'HOME' 
var1 = s.Popen(['/bin/echo', cmd1], stdout=s.PIPE) 
print var1 

リターンこれもまた失敗しました。これを見つけたのは驚くことではありませんが、これは2.6で廃止されました。その後

import os 

var1 = os.popen('echo $HOME') 
print var1 

戻り

<open file 'echo $HOME', mode 'r' at 0x7f1c6b26f6f0> 
sh: echo: I/O error 

私の最後の試み(実際にはそれ以上は...あったが、我々はちょうどこの時にそれを残します)

import subprocess as s 

var1= s.Popen(["echo", "$HOME"], stdout=s.PIPE).communicate()[0] 

print var1 

リターン:

[email protected]:~/Desktop$ python home_test.py 
$HOME 

誰かが指摘できますか?右の方向に?私はこれで一日を過ごしました。私は助けてください。ご協力いただきありがとうございます。

+0

'var1 = s.Popen(['echo'、 '$ HOME']、stdout = s.PIPE)'では、最初の配列要素だけがスクリプトとして扱われます。後続の配列要素は、そのスクリプトへの引数です。 –

+0

... btw、本当のユースケースは何ですか?一般に、 'shell = True'を使うのは間違ったことです。十分な(実質的な!)注意を払って使用しないとセキュリティ上のバグが発生し、Pythonをより冗長にすることで何もできないことはありません。 –

答えて

1

本当に環境変数の値を取得したいと思うようです。 os.getenv('HOME')はそれを行う必要があります。

+0

これはうまくいきませんでしたが、私はその結果をコメントに入れました –

+0

Nevermind、私はタイプミスがありました。これもうまくいった。お二人のおかげです。 –

+1

接線方向の警告:原則として 'os.environ'を排他的に使用し、一貫性のために' getenv'/'putenv'を禁止する方が良いでしょう。具体的には、環境を変更すると問題になります。 'putenv'を呼び出すと' os.environ'は変更されませんが、 'os.environ'も' putenv'(サポートされている場合)を行います。さらに、 'getenv'と' putenv'はすべてのOSで利用できるわけではありませんが(確かに、それはAFAICTをサポートしていないまれなUNIX風のフレーバーです)、 'os.environ'は常にサポートされています。 – ShadowRanger

3

はあなたの試みと結果への答え今

 
import os 
home = os.environ['HOME'] 
print(home) 

で始めることができます。あなたの主な問題(いくつかのランダムなバグに加えて)は、$HOMEがシェルによって環境変数の値に置き換えられています。シェル引数の展開がなければ$HOMEは単なる文字列であり、それがあなたのものです。

+0

ありがとうございました。なぜ私はこれを考えなかったのか分かりません。おそらく、私はサブプロセスを使用しようと壁に頭を打っていたからだろう。 –

+1

あなたの主な問題は、シェルを使わずにシェル変数の展開をしようとしていたことです。 –

+1

@shellsbelles:原則として、単純なシェルユーティリティの大部分は、Pythonの同等のものより優れています。シェルユーティリティの 'サブプロセス 'がより速く現れる場合でも(' .gz'ファイルからの圧縮データの読み込みは表面的に高速です)、通常は 'サブプロセス'が' '空き ''のための並列処理を行いますgzipモジュールの場合、いくつかのバージョンでは、デフォルトではバッファされなかったので、 'io.BufferedReader'ラッピングはそれを修正します)。 Pythonの同等のコードをスレッド化したり並列処理したりすると、あまり失うことはありません。 – ShadowRanger

1

答えはos.environ['HOME']ですが、あなたが移植性を求めているとは限りません。 HOMEが設定されているという保証はありません(これは規約ではなく必須ではなく、ユーザーが削除でき、シェルが設定しないなど)。そして最終的にWindowsへの移植性を望むなら、それはその名前ではありません。あなたがユーザのホームディレクトリをしたい場合は、直接の環境をチェックしません、代わりに、よりスマートホームディレクトリ検索ロジックを使用するos.path.expanduserを使用します。

import os.path 

home = os.path.expanduser('~') 

これはHOMEが定義されていない場合でも動作する、と見上げに一般う他のユーザのホームディレクトリ(os.path.expanduser('~someotheruser'))。

Python 3.5以降では、use pathlib.Path.home() to get a Path object representing the home directoryでも可能です。

また、環境変数置換の大部分で文字列を展開する必要がある場合は、os.path.expandvarsを参照すると、環境参照と文字列の書式設定が1回の操作として実行されます。

関連する問題