如何以另一个用户身份运行交互式命令

Nut*_*tim 4 scripting bash

我正在尝试编写一个 bash 脚本

  • 上下文切换到另一个用户(在本例中为 root)
  • i执行一组命令创建一个用户(交互提示调用者输入用户名)然后ii. 设置该用户的密码
  • 得到一个返回值
  • 然后继续做事,用那个返回值

我到目前为止已经试过一个<< 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

Gil*_*il' 5

sudo su - << 'EOF'
# do stuff...
EOF
Run Code Online (Sandbox Code Playgroud)

这是可行的,但有一个限制:脚本通过其标准输入传递给外壳程序,因此您不能将标准输入用于其他用途,例如读取要创建的用户名。

保留标准输入的简单方法是将 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)