如何在sudo中运行两个命令?


152

有什么方法可以从命令行运行两个Db2命令?(它们将从PHP exec命令中调用。)

  1. db2 connect to ttt (请注意,我们需要为第二个命令启用连接
  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'

第一个命令正确完成,但第二个命令失败并显示错误消息 SQL1024N A database connection does not exist. SQLSTATE=08003

请注意,我需要以php用户身份运行它。sudo -u db2inst1 id作为php用户的命令为我提供了正确的输出。


请留下评论,为什么你想结束这个问题。谢谢。
Radek

1
最终投票是迁移到serverfault,因为这是系统管理问题,而不是编程问题。
bdonlan

Answers:


157

sudo可以通过外壳运行多个命令,例如:

$ sudo -s-'whoami; 我是谁'
根
根

您的命令将类似于:

sudo -u db2inst1 -s-“ db2连接到ttt; db2更新联系人设置EMAIL_ADDRESS ='mytestaccount@gmail.com'”

如果您的sudo版本不适用于带有-s的分号(显然,如果使用某些选项进行编译则不能),则可以使用

须藤-sh -c'whoami; 我是谁'

相反,它基本上具有相同的作用,但使您可以显式命名外壳。


12
这不适用于最新的debian稳定版(压缩)重击:sudo -s -- '/usr/bin/whoami; /usr/bin/whoami' /bin/bash: /usr/bin/whoami; /usr/bin/whoami: No such file or directory
Valor

11
@valor可以sudo -- sh -c 'whoami; whoami;用作“ sudo -s”损坏时的解决方法。我也更新了答案。
wjl 2012年

6
+1表示显示“-sh -c”示例的已编辑版本。谢谢!
京东。

4
您能解释一下为什么需要“-”吗?
维克·塞维尤尤

7
@VicSeedoubleyew --指示到参数的结尾sudo,因此其他所有内容都是命令的一部分;没有它,诸如这样-c的参数可以解释为的参数sudo。这适用于大多数(但不是全部)命令行程序。再举一个(非sudo)示例,要删除一个文件,-f您不能只运行rm -f,对吗?但是您可以运行rm -- -f以删除名为的文件-f
wjl

176

对于您的命令,您还可以参考以下示例:

sudo sh -c 'whoami; whoami'


14
我发现这是一个更可靠的选择。
尼克


42

如果您想处理引号:

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

4
这是最干净的答案,谢谢。也许要添加一条注释“您不能从以下位置运行多个命令sudo-您始终需要欺骗它以执行可以接受多个命令作为参数运行的外壳”
trs

8

一种eval避免使用subshel​​l 的替代方法:

sudo -s eval 'whoami; whoami'

注意:其他使用sudo -s失败的答案是因为引号被传递到bash并作为单个命令运行,因此需要使用eval去除引号。eval更好的解释是这样的答案

在命令中引用也更容易:

$ 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命令都以“ nobody”用户身份运行。


您可以使用单引号和双引号并将其转义。
Radek 2012年

好了,现在不管我在此命令中将umask设置为什么,它没有效果吗?
迈克尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.