sudoで2つのコマンドを実行する方法


152

コマンドラインから2つのDb2コマンドを実行する方法はありますか?(これらはPHP execコマンドから呼び出されます。)

  1. db2 connect to ttt (2番目のコマンドの接続をライブにする必要があることに注意してください
  2. db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'

私はこれを試しました:

sudo -su db2inst1 db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'

最初のコマンドは正常に終了しますが、2番目のコマンドはエラーメッセージで失敗します SQL1024N A database connection does not exist. SQLSTATE=08003

これをphpユーザーとして実行する必要があることに注意してください。phpユーザーsudo -u db2inst1 idとしてのコマンドは私に正しい出力を与えます。


この質問を閉じる理由をコメントに残してください。ありがとうございました。
Radek 2011

1
これはプログラミングではなくシステム管理の問題であるため、近い票がserverfaultへの移行に賛成です。
bdonlan 2011

回答:


157

sudoは、シェルを介して複数のコマンドを実行できます。次に例を示します。

$ sudo -s-'whoami; 私は誰'
ルート
ルート

コマンドは次のようになります。

sudo -u db2inst1 -s-"db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'"

sudoバージョンが-sを使用したセミコロンで機能しない場合(どうやら、特定のオプションでコンパイルした場合は機能しません)、次のように使用できます。

sudo-sh -c 'whoami; 私は誰'

代わりに、基本的に同じことを行いますが、シェルに明示的に名前を付けます。


12
これは最新のdebian安定版(squeeze)bashでは機能しません:sudo -s -- '/usr/bin/whoami; /usr/bin/whoami' /bin/bash: /usr/bin/whoami; /usr/bin/whoami: No such file or directory
Valor

11
sudo -- sh -c 'whoami; whoami;「sudo -s」が壊れている場合の回避策として使用できる@Valor 。答えも更新しました。
wjl

6
「-sh -c」の例を示す編集済みバージョンの+1。ありがとう!
JD。

4
「-」が必要な理由を教えてください。
Vic Seedoubleyew 2016年

7
@VicSeedoubleyewはの--パラメーターの終わりを示しますsudo。そのため、他のすべてはコマンドの一部です。それなしでは、のような-c引数はへの引数として解釈できますsudo。これはほとんどの(すべてではない)コマンドラインプログラムで機能します。別の(-以外のsudo)例として、と呼ばれるファイルを削除するには、を-f実行することはできませんよねrm -f?!しかし、を実行rm -- -fして、というファイルを削除できます-f
wjl

176

コマンドについては、次の例も参照できます。

sudo sh -c 'whoami; whoami'


14
私はこれがより信頼性の高い代替手段であることを発見しました。
Nick


42

引用符を処理したい場合:

sudo -s -- <<EOF
id
pwd
echo "Done."
EOF

4
これは、ここで最も明確な答えです、ありがとう。「複数のコマンドを実行することはできませんsudo-常にそれをだまして、複数のコマンドをパラメーターとして実行するシェルを実行させる必要があります」
trs

8

evalサブシェルの使用を避けるために使用する代替:

sudo -s eval 'whoami; whoami'

注:sudo -s引用符はbashに渡されて単一のコマンドとして実行されるため、evalを使用して引用符を取り除く必要があるため、他の回答は失敗します。evalこのSOの答えはよりよく説明されています

コマンド内での引用も簡単です:

$ sudo -s eval 'whoami; whoami; echo "end;"'
root
root
end;

そして、コマンドが失敗した場合に実行を停止する必要がある場合は、セミコロンの代わりにダブルアンパーサンドを使用します。

$ sudo -s eval 'whoami && whoamit && echo "end;"'
root
/bin/bash: whoamit: command not found

3

この-sオプションは私に-iはうまくいきませんでした。

これは、bashからログサイズを更新する方法の例です。

sudo -u [user] -i -- sh -c 'db2 connect to [database name];db2 update db cfg for [database name] using logsecond 20;db2 update db cfg for [database name] using logprimary 20;'

1

端末で次のように入力します。

$ sudo bash

次に、必要な数のコマンドを記述します。exit完了したら入力します。

自動化する必要がある場合は、script.shファイルを作成して実行します。

$ sudo ./script.sh

1

少し関連するトピックで、SSHを介して同じマルチコマンドsudoを実行したかったのですが、上記のいずれも機能しませんでした。

たとえばUbuntuでは

$ ssh host.name sudo sh -c "whoami; whoami"
[sudo] password for ubuntu:
root
ubuntu

ここ発見されたトリックは、コマンドを二重引用符で囲むことです。

$ ssh host.name sudo sh -c '"whoami; whoami"'
[sudo] password for ubuntu:
root
root

同様に機能する他のオプション:

ssh host.name sudo sh -c "\"whoami; whoami\""
ssh host.name 'sudo sh -c "whoami; whoami"'

原則として、SSHが実行されているクライアントシェルは最も外側の引用符のセットを取り除いていると思うので、二重引用符が必要です。必要に応じて引用符を混ぜて一致させます(例:変数を渡す必要があります)。ただし、特にリモートコマンドが複雑な場合は、YMMVと引用符を使用します。その場合、Ansibleのようなツールがより適切な選択になります。


1

rootのパスワードがわかっている場合は、

su -c "<command1> ; <command2>"  

rootパスワードがわからない場合は、を使用してくださいsudo su -c "<command1> ; <command2>"
DagHøidahl

0

上記の回答では、引用符内で引用することはできません。このソリューションは:

sudo -su nobody umask 0000 \; mkdir -p "$targetdir"

umaskコマンドとmkdir-commandはどちらも「nobody」ユーザーで実行されます。


一重引用符と二重引用符を使用してエスケープできます。
Radek 2012

では、どうしてこのコマンドでumaskを何に設定しても、何の効果もないのでしょうか。
Michael
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.