read
設定スクリプトをダウンロードし、いくつかの設定パラメータを読み、実行したいと思います。
curl http://example.com/provisioning.sh | sh
問題は、デフォルト値を提供するためにパラメータを使用してread
スクリプトからコマンドを呼び出すことです。-i
read -p "Name: " -i joe name
echo $name
スクリプトをダウンロードして+x
権限を設定して実行すると、すべてが正常です。
cat provisioning.sh | sh
次のように実行するか、sh provisioning.sh
次のように失敗した場合:
read: Illegal option -i
shを介して実行している場合、デフォルト値の読み取りのサポートが提供されないのはなぜですか?
しかし、とにかく削除し-i
て残します。
read -p "Name: " name
echo $name
これでスクリプトを実行すると、cat provisioning.sh | sh
何も起こりません。なぜそんなことですか?
Ubuntu 14.04。
答え1
の出力をパイプするcurl
と、sh
スクリプトテキストをシェルの標準入力にし、実行するコマンドとして受け取ります。その後は何も残りませんread
。試しても端末入力に接続されていないため、端末入力から何も得られません。パイプはsh
プロセスの標準入力を置き換えました。
次の質問read -i
はいいえPOSIX sh関数ですが、でサポートする拡張ですbash
。Ubuntuはdash
、基本的に最小限の拡張機能を備えた最小限のPOSIX準拠シェルです/bin/sh
。これが-i
オプションを明示的に拒否する理由です(サポートはしますが-p
)。
より強力なシェルを直接使用している場合は、次のことを試すことができます。
bash <(curl http://example.com/provisioning.sh)
bash
の出力を読み取るためのパイプを生成し、curl
それをスクリプトファイル引数として提供します。この場合、スクリプトの標準入力はまだターミナルに接続されていてread
動作します(ただし、その行の下に重要な警告があります)。
私がまた注目したいのは" curl | sh
"はい一般的に言えば チプリン顔 ~上明らかなセキュリティ上の問題ですが、スクリプトの状況はユーザーが最もよく知っています。
答え2
別の移植性のあるアプローチは、別のファイル記述子を作成することです。
exec 3<>/dev/tty
read -u 3 -p "Gimme some stuff: " stuff
私の場合、これがうまくいくようにスクリプトですばやく検索して置き換えました。
exec 3<>/dev/tty
read_cmd="read -u 3"
$read_cmd -p "name: " my_name
$read_cmd -p "email: " my_email
$read_cmd -s -p "password: " my_password