Answers:
另一种方法是将完整的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
在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 ,以避免出现虚假的换行符。
sudo -s
万一root
用户有(相当糟糕的)想法来改变它的外壳,使用它是不好的。确实应该sudo sh
明确指出要使用哪个外壳。