別のユーザーとして対話型コマンドを実行する方法

別のユーザーとして対話型コマンドを実行する方法

私はbashスクリプトを書こうとしています

  • コンテキストが別のユーザー(この場合はroot)に切り替わります
  • 一連のコマンドを実行して私。ユーザーを作成し(対話的に呼び出し元にユーザー名を尋ねます)、ii.そのユーザーのパスワードを設定する
  • 戻り値を取得する
  • そして、その戻り値を使って処理を続けます

これまで私は<< EOF入力(図1)、 機能 (図2)、および別のスクリプトをプル/実行します(図3)。しかし、必要な結果が得られませんでした。

sudo su - << 'EOF'
# do stuff...
EOF

図1

function myfunc()
{
    local  myresult='some value'
    echo "$myresult"
}

図2

sudo su - -c bash <(curl -fksSL https://<my-script-location>.sh)

図3

答え1

sudo su - << 'EOF'
# do stuff...
EOF

これは機能しますが、制限があります。スクリプトは標準入力でシェルに渡されるため、作成するユーザーの名前の読み取りなど、他の目的で標準入力を使用することはできません。

標準入力を保持する簡単な方法は、代わりにシェル コマンドを引数として渡すことです。

sudo suは冗長であることに注意してください。sudo指定されたコマンドを root として実行します。これが の唯一の目的でsuもあります。ログイン シェルを root として実行する場合 (ここではおそらく不要です)、または単にシェルを root として実行する場合はsudo -i、 の代わりにを使用します。sudo su -sudo sh

sudo sh -c '
  # do stuff...
'

これにより、シェルスニペットでシングルクォートを使用するのが難しくなります。'\''シングルクォートリテラル内にシングルクォートを配置するには、を使用します。ヒアドキュメント構造を保持したい場合は、いくつかの方法があります。最も簡単な方法は、ヒアドキュメントを渡すことです。別の記述子でただし、このclosefrom_overrideオプションは sudo 設定で有効にする必要がありますが、デフォルトでは有効になっていません。デフォルトでは、sudostdin、stdout、stderr 以外のすべてのファイル記述子が閉じられます。

sudo -C 3 sh -c '. /dev/fd/3' 3<<'EOF'
# do stuff...
EOF

このオプションが有効になっていないマシンにコードを移植可能にしたい場合は、ヒアドキュメントからスクリプトを読み取り、それを引数としてシェルに渡すことができます。

script=$(cat <<'EOF'
# do stuff...
EOF
)
sudo sh -c "$script"

あるいは、sudo スクリプトをターミナルから読み取れるようにしたい場合は、スクリプト本体を標準入力に渡すことができます。この方法の制限は、スクリプト全体の入力をリダイレクトできないことです。

sudo sh <<'EOF'
exec </dev/tty
# do stuff...
EOF

答え2

呼び出すユーザーがsudoを割り当てることができる場合tty:

Defaults someuser:requiretty

ans には、必要なコマンドを root として実行する権限が付与されています。

Cmnd_Alias STUFF = /usr/bin/passwd, /usr/sbin/useradd
someuser ALL = STUFF

呼び出しを含むスクリプトはsudo対話型になります。ユーザー名を位置引数として渡すことができます。

sudo useradd $1
sudo passwd $1

で通常通り返品ステータスを確認します$?

答え3

su -c '. /dev/fd/4' 4<<\SCRIPT
    ...automated stuff here...
    ....then for interactive...
    exec </dev/tty
SCRIPT

これで完了です。必要に応じて調整してください。ただし、コンテキストが切り替わり、$?完了するとシェルの戻りステータスが in になります。

関連情報