私は次のことをしようとします:
sudo su <<EOF
select x in a b c; do echo "Selected $x"; break; done
EOF
ただし、入力を承認せずに終了します。
これはうまくいきます。
sudo su -c 'select x in a b c; do echo $x; break; done'
しかし、heredocに長いスクリプトを書く方が良いでしょう(例えば、ファイルに入れる方が良いことがわかります)。
この質問に対する答えはどこにでもあると確信していますが、bash/heredoc/tty/stdinの正しいクエリの組み合わせが見つからないようです。
これを達成する方法はありますか?
答え1
問題は、select
hereドキュメントにリダイレクトされる標準入力から読み取ろうとすることです。プロンプトに対する応答がないため、エラーが発生します。
回避策は、ここで説明されているように入力を端末にリダイレクトすることです。
sudo -s <<'EOF'
select x in a b c; do
echo "Selected $x"
break
done </dev/tty
EOF
EOF
また、here-docで変数が拡張されるのを防ぐには、周囲に引用符を入れる必要があります。それ以外の場合は、$x
値を取得したサブシェルではなく元のシェルから拡張されますselect
。
答え2
残りの部分を別のものとして実行するには、ファイルを使用する1つの方法があります。
$ cat asdf
who am i
sudo su
who am i
$ bash < asdf
jhldoe tty?? Jun 7 16:30
root tty?? Jun 7 16:30
$
より簡単なのは、標準入力が提供されたシェルがこれらのコマンドを実行することです。
$ sudo sh <<EOF
> who am i
> pwd
> EOF
root tty?? Jun 7 16:31
/var/tmp
$
標準入力を読み取って端末にアクセスする問題に私の解決策を使用することができました。feed
スクリプト(文書、ユニットテスト、.feedrc
ルートのホームディレクトリ)。
$ (echo 'select x in a b c; do echo "Selected $x"; break; done') | sudo feed - bash
これにより、ルートシェルに入り、入力がそのシェルにプッシュされるため、ユーザーの要件に適している場合とそうでない場合があります。