2017-04-08 7 views
1

何かを実行するには、何かを実行するためにcurl xxx | bashを使用する必要があります。 私はこのようなテストにsys.stdin.readline()でPythonスクリプトを作成しました:"| bash" by sys.stdin.readline()でPythonスクリプトを実行する

[python3] test.py 


import sys 
def read_input(): 
    input = sys.stdin.readline().rstrip() 
    print(input) 
read_input() 

それは直接python3 test.py

test 
test 

によって運営しかし、私はecho 'python3 test.py' | bashを使用している場合、それは私に入力何かをできるように停止することはありません動作します。

ヒント?

答えて

2

|でパイプすると、最初のコマンドの出力を2番目のコマンドの入力にリダイレクトします。つまり、2番目のコマンドの標準入力は端末に接続されないため、キーボード入力を読み取ることができません。したがって、フォームcurl xxx | bashは、非対話型スクリプトの場合にのみ機能します。これは決してPython特有のものではありません。

あなたは別の番号の下に入力記述子を保存することで、この周りの原則作業ではできたが、それは非常に複雑取得ん:ここで私は標準入力をファイルに複製されているサブシェルを作成するために()を使用

$ (echo 'exec <&3 3<&- ; echo script starts ; read hello ; echo you entered $hello ; exit' | bash) 3<&0 
script starts 
something 
you entered something 

ディスクリプタ3は3<&0を使用し、パイプラインで生成されたスクリプトはexec <&3 3<&-exitのstdinの名前を変更して、復元されたstdinからのさらなるコマンドの読み取りを防ぎます。これには、echoコマンドで記述子3が開いているなどの副作用があります。

最初にcurl address | bashを使用する主な理由は、コマンドをシンプルにすることです。これは、あなたが後にしていることではありません。また、ダウンロード中に何か問題が発生した場合、パイプが処理できなくなります。あなたのスクリプトはどこにでも中断することができます。その後の実行伝統的なダウンロードはそれほど悪いことではありません。比較すると

curl -O http://somewhere/somefile.py && python somefile.py 

が、これはあなたのファイルシステムにsomefile.pyが保存されます。そこには、書き込み可能なファイルシステムを必要とし、その特定のファイル名を置き換えるというような短所があります。逆に何かがうまくいかない場合、それはそこで停止し、&&のために壊れたスクリプトを実行しません。

最後にひとつの可能性は、コマンドラインに収まるをダウンロードしているスクリプトはパイプではなく、そこにそれを置くためにあるかもしれない場合:これは、中断のダウンロードに同じ弱点を運ぶ

python -c "$(curl $url)" 

、さらに場所コマンドラインのスクリプトの内容は一般的には公開情報です(ps axの出力を検討する)。しかし、カールを使ってスクリプトをダウンロードしているだけであれば、そのスクリプトを入手する方法についての情報もありました。これは標準入力をリダイレクトしないので、あなたの直接の質問に対する答えかもしれません。一般的に

、私はこのcurl something | bashコマンドラインがするように、検証せずにまっすぐインターネットオフ任意のスクリプトを実行するないをお勧めします。それは、ハイジャックするのがあまりにも脆弱です。どんなステップでも検証が行われないからです。 aptなどの署名をチェックするパッケージリポジトリを使用する方がよいでしょう。

Linux上の端末にアクセスするもう1つの方法は、デバイス/dev/ttyです。このメソッドは、たとえばwhen ssh asks for a passwordに使用されます。 (exec < /dev/null ; read foo <&2 ; echo $foo)のように、stdoutまたはstderrを入力用に再び開くこともできます。

関連する問題