web-dev-qa-db-ja.com

bash、新しいシェルを呼び出した後にコマンドを実行する

私はこのようなスクリプトを作成しようとしています:

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

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

何か助けは?

12
Matteo

問題はSudo -sであり、引数を指定しないとrootの対話型シェルが開きます。

Sudo -sを使用して単一のコマンドを実行するだけの場合は、次のように簡単に実行できます。

Sudo -s command

例えば ​​:

$ Sudo -s whoami
root

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

$ Sudo -s <<<'whoami'
root

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

$ Sudo -s <<'EOF'
> whoami
> hostname
> EOF
root
something--
7
heemayl

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

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

ただし、より良い方法は、代わりにSudoを付けてscriptを起動することです。スクリプト内に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
7
terdon

Bourne Shellには-cフラグがあり、これを使用してシェルに任意のスクリプトを渡すことができるため、次のように記述できます。

Sudo sh -c 'something'

ただし、これは最も単純なコマンドにのみ役立ちます。スクリプトを正しく引用するのは非常に面倒であり、sshを介してリモートサーバーにコマンドを送信すると、引数のスクリプトが1回はスクリプトを送信する側で、もう1回はスクリプトを実行する側で分析されます。

somethingが複雑なスクリプトである場合、またはssh行を介して渡す必要がある場合は、スクリプト何かを書き込むことを目的とする関数prepare_something_scriptを作成するのが一般的です'onstdout。最も単純な形式では、この関数はヒアドキュメントを使用して出力を生成できます。

prepare_something_script()
{
  cat <<EOF
something
EOF
}

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

prepare_something_script | Sudo sh

Sudoによって付与された特権を使用してリモートでスクリプトを実行する必要があるシナリオでは、このようにsshの標準入力のリダイレクトを回避するために、スクリプトをbase 64でエンコードするのが通例です。 :

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

そのコードを関数で使用する場合は、something64変数をlocalとしてマークすることを忘れないでください。 base64の一部の実装は、デコードする-dフラグを提供します。これは、詳細な--decodeバリアントよりもサポートが不十分です。一部の実装では、誤った改行を避けるために、エンコーディングコマンドに-w 0を追加する必要があります。

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

Sudo -s something...
0
soumen