我无法弄清楚这有什么问题。当我在终端中运行并输入密码时,没有任何反应,但如果我在终端中单独运行每个命令,它就可以工作。谢谢!
#!/bin/bash
sudo su;
mkdir /opt/D3GO/;
cp `pwd`/D3GO /opt/D3GO/;
cp `pwd`/D3GO.png /opt/D3GO/;
cp `pwd`/D3GO.desktop /usr/share/applications/;
chmod +x /opt/D3GO/D3GO
答案 0 :(得分:15)
命令sudo su
启动一个交互式root shell,但它不会将当前shell转换为根目录。
做你想做的事的成语就像这样(感谢@CharlesDuffy的额外细心):
#check for root
UID=$(id -u)
if [ x$UID != x0 ]
then
#Beware of how you compose the command
printf -v cmd_str '%q ' "$0" "$@"
exec sudo su -c "$cmd_str"
fi
#I am root
mkdir /opt/D3GO/
#and the rest of your commands
我们的想法是检查当前用户是否为root用户,如果没有,请使用su
重新运行相同的命令
答案 1 :(得分:14)
您可以使用Here Documents将输入重定向到交互式shell脚本。运算符<<
是一个读取输入的指令,直到找到包含指定分隔符的行为EOF
(文件末尾)。
sudo su <<EOF
echo "code"
EOF
e.g。
#!/bin/bash
sudo su <<EOF
mkdir /opt/D3GO/
cp `pwd`/D3GO /opt/D3GO/
cp `pwd`/D3GO.png /opt/D3GO/
cp `pwd`/D3GO.desktop /usr/share/applications/
chmod +x /opt/D3GO/D3GO
EOF
答案 2 :(得分:8)
sudo su
不是在shell中运行的命令 - 它启动一个新shell 。
新的shell不再运行您的脚本, 运行脚本的旧shell等待新的shell继续运行。
答案 3 :(得分:8)
accepted answer效果很好,但使用sudo
按需重新调用自身的习惯用法可以简化并制作<强>更便携:
[[ $(id -u) -eq 0 ]] || exec sudo /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
使用[[ ... ]]
代替[ ... ]
会使x
前置操作数(或双引LHS)不必要。
使用bash -c
代替su -c
来解释重构的命令行会使命令更具可移植性,因为并非所有平台都支持su -c
(例如,macOS不支持)。
在bash
中,$BASH_SOURCE
通常是更可靠的方式来引用正在运行的脚本。
使用上述方法,参数中的任何变量引用或命令/算术替换都会被调用 shell扩展。
如果你想要 延迟扩展 - 那么在sudo
shell运行之前不会扩展变量引用,在 root 用户 - 使用此:
(( __reinvoked )) || exec sudo -s __reinvoked=1 "$BASH_SOURCE" "$@"
请注意,您必须单 - 引用包含变量引用或命令替换的任何参数,以便对它们进行延迟扩展;例如,'$USER'
。
请注意使用ad-hoc环境变量__reinvoked
来确保重新调用一次(即使最初已经以root用户身份调用过)。
这是演示第一种技术的示例脚本:
如果未以root用户身份调用,则脚本会使用sudo -s
重新启动自身,并按原样传递所有参数。
除非事先经过身份验证且仍处于超时期限内,否则sudo
会提示输入管理员密码。
#!/bin/bash
[[ $(id -u) -eq 0 ]] || exec sudo /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
# Print the username and all arguments.
echo "Running as: $(id -un)"
echo "Arguments:"
for arg; do echo " $((++i)): [$arg]"; done
acfreitas's helpful answer演示“脚本内部脚本”技术,其中 here-document 用于通过stdin向{{提供shell代码1}}。
同样, sudo su
已足够且引用很重要:
sudo -s
请注意此处的开头文档分隔符{@ 1}}在这种情况下是引用,以防止文档内容从预先由当前 shell解释
如果您没有引用({1}}的任何部分,sudo -s -H <<'EOF'
echo "$HOME"
EOF
将扩展到当前用户的主目录。
如果您想 混合预先扩展和延迟扩展,请在此处打开 - 文档分隔符不加引号并有选择地{{1} } -quote EOF
实例:
EOF
答案 4 :(得分:2)
因为运行“sudo su”会打开一个新shell,并且在退出该shell之前命令不会返回。也许将脚本分成2个文件:第一个运行sudo并在sudo下执行第二个脚本。
答案 5 :(得分:2)
sudo su将尝试以root身份启动新shell。 打开新shell后,原始脚本将不会继续,直到新shell关闭。
要修复,请尝试:
在shell脚本中尝试:
su <username> -c "my command"
因此,如果用户是“userA”:
su userA -c "mkdir /opt/D3GO/"
但是,如果您是userA,并且您希望以root身份运行脚本部分,系统将提示您输入通行证。
su root -c "mkdir /opt/D3GO/"
您也可以通过首先使用sudo运行脚本来解决这个问题
sudo ./myScript.sh
这样,脚本会保留脚本中的原始用户,您可以使用 $ {USERNAME} , $ {等标准变量访问该脚本UID} 等
取决于哪种方式更适合你。