Bash,调用新的shell后执行命令


12

我正在尝试制作一个像这样的脚本:

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

当我执行它时,我得到一个新的外壳,但是something仅当我退出由创建的外壳时才执行sudo -s,而不是在其内部执行。

有什么帮助吗?

Answers:


7

问题是sudo -s没有任何参数就会为root打开一个交互式shell。

如果您只想使用来运行单个命令sudo -s,则可以执行以下操作:

sudo -s command

例如 :

$ sudo -s whoami
root

或者您可以在这里使用字符串:

$ sudo -s <<<'whoami'
root

如果您有多个命令,则可以在此处使用doc:

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

1
sudo -s万一root用户有(相当糟糕的)想法来改变它的外壳,使用它是不好的。确实应该sudo sh明确指出要使用哪个外壳。
Michael Le BarbierGrünewald2015年

7

另一种方法是将完整的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

3

Bourne shell中有一个-c,你可以使用任意的脚本传递给shell标志,这样就可以写类似

sudo sh -c 'something'

但是,这仅对最简单的命令有用,因为正确引用脚本非常麻烦,并且如果您通过ssh将命令发送到远程服务器,则不便之处甚至更大,因为参数脚本将被分析两次,一次在侧面发送脚本,然后一次运行脚本。

如果something是复杂的脚本或需要通过ssh行传递,通常的做法是编写一个函数,prepare_something_script其功能是在stdout上编写脚本“ something” 。以最简单的形式,此函数可以使用here-document生成其输出:

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"

如果在函数中使用该代码,请不要忘记将something64变量标记为local。一些base64的实现提供了一个-d标志来进行解码,与详细--decode变体相比,它的支持程度较低。某些实现要求-w 0在编码命令中添加a ,以避免出现虚假的换行符。


0

您需要在sudo -s之前添加命令,而不是在下一行中添加命令。

sudo -s something...
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.