私は gnome-terminal 用のカスタム起動コマンドを作成しており、起動するたびにウェルカム メッセージを表示するつもりです。
メッセージは正しく表示されます。0.09 秒の時間レートで文字が 1 つずつ表示されるようにコーディングしました。
echo -n "W"
sleep 0.09
echo -n "e"
sleep 0.09
echo -n "l"
sleep 0.09
echo -n "c"
sleep 0.09
echo -n "o"
sleep 0.09
echo -n "m"
sleep 0.09
echo -n "e"
sleep 0.09
テスト中に、文字の表示を止めて直接開始できれば非常に便利だと思いましたsu
。次の解決策を思いつきました。
su --command "read -n 1 -s key; if [[ "$key" == "g" ]]; then echo "Test Successful."; else echo "Test Failed."; fi;"
su -c
bash が怒って をスローしないようにするには、を使用する必要がありますillegal action: read -n
。このコード スニペットは、bash が 1 行のコマンドの組み合わせをどのように読み取るかをテストしたかったため、デバッグ目的のみに使用されます。
主な問題は、このコードを構成ファイル (起動用のカスタム コマンドを記述したファイル) から実行しようとしたときに発生します。Bash は次を返します:
No passwd entry for user 'Successful.; else echo Test'
Welcome
不思議なことに、デフォルトのプロファイルで同じコマンド ( なしsu -c
) を実行すると完璧に動作しますが、 su -c で実行すると動作しません。
デフォルト プロファイルで他のコマンドを試し、入力してsu -c "echo Hi"
正常に動作しました。なぜこのようなことが起こるのでしょうか? 何か心当たりはありますか?
答え1
コマンド全体を二重引用符ではなく一重引用符で囲みます。最初に注意すべきことは、変数 ($key) があることです。二重引用符で囲むと、シェルによって置換されてから引数になりますsu
。次に、引用符が現在のものと一致するかどうかについてですが、二重引用符を使用すると、引数は次のように分割されます。
- 引数0:
su
- 引数1:
--command
- 引数2:
read -n 1 -s key; if [ <value of $key or nothing> == g ]; then echo Test
- 引数3:
Successful.; else echo Test
- 引数4:
Failed.; fi;
引数全体を一重引用符で囲むと、この文字列をそのまま 2 番目の引数として渡すことで、変数の置換を回避し、分割の奇妙さを修正するという 2 つの問題を修正できますsu
。
ボーナス: 一般的な注意として、可能であればテストで二重括弧を使用しないでください。これはバシズム (bash でのみ機能し、より互換性のある対応する部分に置き換えることができる構文) です。
次のバージョンは期待どおりに動作するはずです。
su --command 'read -n 1 -s key; if [ "$key" == "g" ]; then echo "Test Successful."; else echo "Test Failed."; fi;'