我正在尝试编写一个 bash 脚本
- 上下文切换到另一个用户(在本例中为 root)
- 执行一组命令我。创建一个用户(交互式提示调用者输入用户名)然后二.设置该用户的密码
- 得到一个返回值
- 然后继续做一些事情,并返回值
到目前为止我已经尝试过 << EOF 输入(图。1),一个函数(图2),并拉动/运行一个单独的脚本(图3)。但是我还没有得到我需要的结果。
sudo su - << 'EOF'
# do stuff...
EOF
图。1
function myfunc()
{
local myresult='some value'
echo "$myresult"
}
图2
sudo su - -c bash <(curl -fksSL https://<my-script-location>.sh)
图3
答案1
sudo su - << 'EOF' # do stuff... EOF
这是可行的,但有一个限制:脚本通过其标准输入传递到 shell,因此您无法将标准输入用于其他用途,例如读取要创建的用户的名称。
保留标准输入的简单方法是将 shell 命令作为参数传递。
请注意,这sudo su
是多余的 -sudo
以 root 身份运行指定的命令,这su
也是唯一的目的。如果您想以 root 身份运行登录 shell(这在这里可能是不必要的)或者只是以 root 身份运行 shell,请使用sudo -i
而不是。sudo su -
sudo sh
sudo sh -c '
# do stuff...
'
这使得在 shell 代码片段中使用单引号变得很尴尬。您可以'\''
在单引号文字内放置单引号。如果你想保留here文档结构,有几种方法。最直接的就是传here文档在不同的描述符上。然而,这需要closefrom_override
在 sudo 配置中激活该选项,默认情况下并非如此;默认情况下,sudo
关闭除 stdin、stdout 和 stderr 之外的所有文件描述符。
sudo -C 3 sh -c '. /dev/fd/3' 3<<'EOF'
# do stuff...
EOF
如果您希望代码可移植到未激活此选项的计算机,则可以从heredoc读取脚本并将其作为参数传递给shell。
script=$(cat <<'EOF'
# do stuff...
EOF
)
sudo sh -c "$script"
或者,如果您希望 sudoed 脚本能够从终端读取,则可以在标准输入上传递脚本主体。这种方法的一个限制是它不允许重定向整个脚本的输入。
sudo sh <<'EOF'
exec </dev/tty
# do stuff...
EOF
答案2
假设调用的用户sudo
可以分配tty
:
Defaults someuser:requiretty
ans 已被授予以 root 身份执行所需命令的权限:
Cmnd_Alias STUFF = /usr/bin/passwd, /usr/sbin/useradd
someuser ALL = STUFF
包含调用的脚本sudo
将是交互式的。您可以将用户名作为位置参数传递:
sudo useradd $1
sudo passwd $1
并像往常一样使用 来检查返回状态$?
。
答案3
su -c '. /dev/fd/4' 4<<\SCRIPT
...automated stuff here...
....then for interactive...
exec </dev/tty
SCRIPT
应该做。定制它以满足您的需求 - 但它会切换上下文,并且$?
当您完成它时,shell 的返回状态将处于。