現在、ttyに接続されているsuを介してheredocスクリプトを実行します。

現在、ttyに接続されているsuを介してheredocスクリプトを実行します。

私は次のことをしようとします:

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

問題は、selecthereドキュメントにリダイレクトされる標準入力から読み取ろうとすることです。プロンプトに対する応答がないため、エラーが発生します。

回避策は、ここで説明されているように入力を端末にリダイレクトすることです。

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

これにより、ルートシェルに入り、入力がそのシェルにプッシュされるため、ユーザーの要件に適している場合とそうでない場合があります。

関連情報