Bash、新しいシェルを呼び出してコマンドを実行します。

Bash、新しいシェルを呼び出してコマンドを実行します。

次のスクリプトを作成しようとしています。

#!/bin/bash
sudo -s
something...

実行すると、新しいシェルが作成されますが、シェルの内部ではなく作成されたsomethingシェルを終了したときにのみ実行されます。sudo -s

助けが必要ですか?

答え1

別の方法は、完全なbashコマンドを次に渡すことですsudo

#!/bin/bash
sudo bash -c 'command1; command2; command3;'

しかし、より良いアプローチは始めることです。スクリプトそしてsudoその逆です。これをsudoスクリプトに入れるのは良い考えではありません。 root権限()でスクリプト全体を実行するのが最善ですsudo script.sh。必要にsudo応じて、その権限を使用して特定のコマンドを削除できます。たとえば、

#!/usr/bin/env bash
whoami
echo $HOME
sudo -u terdon whoami  ## drop privileges for specific command.

上記のスクリプトを実行すると、次のものが返されます。

$ sudo ~/scripts/a.sh
root
/root
terdon

答え2

問題は、sudo -sパラメータがルートの対話型シェルを開かないことです。

以下を使用して単一のコマンドを実行する場合sudo -s

sudo -s command

たとえば、

$ sudo -s whoami
root

または、ここで文字列を使用できます。

$ sudo -s <<<'whoami'
root

複数のコマンドがある場合は、ここでドキュメントを使用できます。

$ sudo -s <<'EOF'
> whoami
> hostname
> EOF
root
something--

答え3

これボンシェル-c任意のスクリプトをシェルに渡すために使用できるフラグがあるため、次のように書くことができます。

sudo sh -c 'something'

ただし、これは最も単純なコマンドにのみ役立ちます。スクリプトを適切に参照するのは面倒であり、コマンドが以下を介してリモートサーバーに送信される場合はさらに不便です。SSHパラメータスクリプトは、スクリプトを送信する側で1回、スクリプトを実行する側で1回、2回解析されるためです。

something複雑なスクリプトSSHprepare_something_scriptさて、一般的な慣行は、その上に「何か」をスクリプトとして書く関数を書くことです。標準出力。最も単純な形式では、関数はこのドキュメントを使用して出力を生成できます。

prepare_something_script()
{
  cat <<EOF
something
EOF
}

prepare_something_scriptその後、生成されたスクリプトは、付与された権限を使用してローカルで実行できます。Sudo次のように:

prepare_something_script | sudo sh

付与された権限を使用してスクリプトをリモートで実行する必要があるシナリオでは、Sudo標準入力リダイレクトを防ぐために、スクリプトは通常 Base 64 でエンコードされます。SSH、このように:

something64=$(prepare_something_script | base64)
ssh usesr@remote-host "echo ${something64} | base64 --decode | sudo sh"

関数でこのコードを使用している場合は、以下を表示することを忘れないでください。何か64変数は地元の。いくつかの実装64ビットベース-dverboseバリアントよりもサポートが少ないデコードするフラグを提供します--decode。いくつかの実装では、-w 0偽の改行を防ぐためにエンコードコマンドにaを追加する必要があります。

答え4

次の行ではなくsudo -sの前にコマンドを追加する必要があります。

sudo -s something...

関連情報