Bashで外部プログラムを対話的に実行するには?

Bashで外部プログラムを対話的に実行するには?

たとえば、シェルスクリプトからPythonで何かを実行するには、次のようにします。

    echo 'print("hello world")' | python2

今、インタラクティブなタスクを実行したいと想像してみてください。つまり、私からの入力が必要です。

    name = raw_input("Enter your name:")

以下を実行してください。

    echo 'name = raw_input("Enter your name:")' | python2

エラーが発生します。それでは、bashで対話できるものを実行する正しい方法は何ですか?

PS - これは単なる例です。 Python以外の外部プログラムで一連のスクリプトを実行する必要があります。その中にはユーザーの入力が必要です。入力が必要になるまですべてがスムーズに実行され、現在のスクリプトがクラッシュして次のスクリプトに渡されます。

ありがとうございます:)

ベストアンサー1

プログラムを文字列としてコマンドインタープリタにパイプすると、インタプリタは標準入力からそれを読み込み、標準入力がパイプの読み取り端にバインドされるようにします。提供された情報と対話しようとするコマンドは通常EOFです。

たとえば、

$ echo 'read x; echo "$x"' | bash
  # Just prints an empty line, doesn't wait for input

これが機能するには、次のものが必要です。

  • パイプライン全体を実行するプロセスの標準入力コピーから生成された他のファイル記述子から対話的に提供された入力を読み取るようにスクリプトを再構築します。

    { echo '0<&3 read x; echo "$x"' | bash; } 3<&0
    

    Pythonを例に挙げると、次のようになります(簡単な説明のために私はPythonプログラマーではありません)。

    { echo 'import sys; \
      sys.stdin = open("/dev/fd/3"); \
      name = raw_input("Enter your name:")' | python2
    } 3<&0
    

    または

  • インタプリタが他のファイル記述子を読み取るようにし、読み取った合計をパイプにバインドし、パイプ全体を実行するプロセスの標準入力を使用できるように、いくつかのファイル記述子を混在させます。インタプリタがスクリプトを引数として受け入れ、プラットフォームがファイル/dev/fd/n記述子にアクセスする方法をサポートしているとします。

    { echo 'read x; echo "$x"' | bash /dev/fd/3 3<&0 0<&4; } 4<&0
    

    サンプルPythonスクリプトの場合:

    { echo 'name = raw_input("Enter your name:")' |
      { python2 /dev/fd/3
      } 3<&0 0<&4
    } 4<&0
    

    または

  • 外部プログラムがスクリプトを引数として受け入れず(などの文字列でもbash -c 'echo "foo"'、などのファイル名でもないbash /dev/fd/3)、標準入力からスクリプトと対話型の入力を読み取る必要がある場合は、次の行でSomethingを使用できます。 :

    { echo 'echo start; echo "foo? "; read x; echo "$x"; echo end' |
      bash -c '0<&3 cat -
        while IFS= read -r x
        do
          printf "%s\n" "$x"
        done' 3<&0 0<&4 |
      bash
    } 4<&0
    

おすすめ記事