我正在尝试编写一个 bash 脚本
我到目前为止已经试过一个<< EOF输入(图1),功能(图2),和拉/运行一个单独的脚本(图3)。但是我还没有得到我需要的结果。
sudo su - << 'EOF'
# do stuff...
EOF
Run Code Online (Sandbox Code Playgroud)
图。1
function myfunc()
{
local myresult='some value'
echo "$myresult"
}
Run Code Online (Sandbox Code Playgroud)
图2
sudo su - -c bash <(curl -fksSL https://<my-script-location>.sh)
Run Code Online (Sandbox Code Playgroud)
图3
Run Code Online (Sandbox Code Playgroud)sudo su - << 'EOF' # do stuff... EOF
这是可行的,但有一个限制:脚本通过其标准输入传递给外壳程序,因此您不能将标准输入用于其他用途,例如读取要创建的用户名。
保留标准输入的简单方法是将 shell 命令作为参数传递。
请注意,这sudo su是多余的——sudo以 root 身份运行指定的命令,这也是唯一的目的su。如果您想以 root 身份运行登录 shell(这在此处可能是不必要的)或仅以root 身份运行 shell,请使用sudo -i代替。sudo su -sudo sh
sudo sh -c '
# do stuff...
'
Run Code Online (Sandbox Code Playgroud)
这使得在 shell 代码段中使用单引号变得很尴尬。您可以使用'\''将单引号放在单引号文字中。如果要保留此处的文档结构,有几种方法。最直接的方法是在不同的描述符上传递 here 文档。但是,这需要closefrom_override在 sudo 配置中激活该选项,默认情况下并非如此;默认情况下,sudo关闭除标准输入、标准输出和标准错误之外的所有文件描述符。
sudo -C 3 sh -c '. /dev/fd/3' 3<<'EOF'
# do stuff...
EOF
Run Code Online (Sandbox Code Playgroud)
如果您希望您的代码可移植到未激活此选项的机器上,您可以从 heredoc 读取脚本并将其作为参数传递给 shell。
script=$(cat <<'EOF'
# do stuff...
EOF
)
sudo sh -c "$script"
Run Code Online (Sandbox Code Playgroud)
或者,如果您希望 sudoed 脚本能够从终端读取,您可以在标准输入上传递脚本主体。这种方法的一个限制是它不允许重定向整个脚本的输入。
sudo sh <<'EOF'
exec </dev/tty
# do stuff...
EOF
Run Code Online (Sandbox Code Playgroud)