如何在脚本中运行“sudo”命令?

use*_*948 126 root sudo scripts

要手动打补丁,我必须输入这个命令

sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  
Run Code Online (Sandbox Code Playgroud)

09之前有一个空格:

sudo ./playback_delete_data_patch.sh [space] 09_delete_old_data_p.sql
Run Code Online (Sandbox Code Playgroud)

如何在脚本中运行它?

还有其他几个命令,但这个命令有问题。

ter*_*don 148

拥有sudo内部脚本很少是一个好主意。相反,sudo从脚本中删除并使用以下命令运行脚本本身sudo

sudo myscript.sh
Run Code Online (Sandbox Code Playgroud)

这样,脚本中的所有命令都将以 root 权限运行,并且您只需在启动脚本时提供一次密码。如果您需要在没有sudo特权的情况下运行脚本中的特定命令,您可以以普通用户身份运行它(感谢Lie Ryan):

sudo -u username command 
Run Code Online (Sandbox Code Playgroud)

空格是不相关的,它不应该影响任何东西,命令和它的参数之间总是有一个空格。

  • 我编写的很多脚本都会进行大量的用户交互和/或错误检查。然后最后的一个命令 - 类似于 rsync - 需要以 root 身份运行。为什么我想让整个事情运行起来,让自己对可能包含严重错误或具有 root 访问权限的漏洞的许多代码行开放——尤其是在调试时——当只有一个或几个命令需要访问权限时? (68认同)
  • 脚本中可能有不需要 root 权限的命令,您可以使用 sudo -u username 临时删除这些命令的 root 权限 (41认同)
  • @Joe 在这里有一个很好的观点。此外,当有人说*不要那样做*时,很高兴确切知道为什么会这样,或者至少,在哪种情况下我不应该这样做,以及为什么 (14认同)
  • @terdon 你没有在听。我知道如果你以 root_ 身份运行脚本,它永远不会提示你输入 sudo。我将其与 _not 以 root 身份运行脚本进行比较,而是在脚本中放置显式的 `sudo` 调用,因为如果只有少数几个需要 root 的狭窄操作,将整个脚本提升为 root 可能是一个糟糕的主意。在这种情况下,我专门回应了您的评论:“主要是因为这意味着您无法自动运行脚本,因为每次被问到时都需要输入密码。” (13认同)
  • @Joe 够公平的。将“从来不是一个好主意”改为“很少”。 (2认同)
  • 当 sudo 在脚本上运行时,它会将 $SUDO_USER 环境变量设置为调用该脚本的用户。与 sudo -u 一起使用时很有用 (2认同)
  • @BeeOnRope 不,这就是我要说的。如果您使用 `sudo script` 启动了脚本,它*永远*不会在脚本内为任何 `sudo` 调用提示输入密码。超时与它无关。一旦使用 `sudo` 启动,脚本就会以 root 身份运行,并且 root 永远不需要为 `sudo` 输入密码。您可以使用 `sudo -i`(启动一个 root shell)然后使用 `sudo ls` 来测试它,你会看到它不会提示你。更确切地说,您可以运行 `sudo -k` 来重置密码时间戳,它仍然不会提示。如果您是 root,Sudo 永远不会提示。 (2认同)
  • ...我指出,对于大多数脚本,无论您选择使用某些命令运行“sudo script.sh”还是仅“script.sh”,您都将被打印“相同次数”(零或一次)的凭据脚本中以 sudo 为前缀。唯一的例外是运行时间超过 sudo 超时的脚本。本质上,我同意并围绕@Joe 的上述评论提供了一些额外的想法。 (2认同)

Kla*_*cha 51

您可能会修改该sudoers文件。

运行sudo visudo

为您的用户名和脚本添加一个条目,您希望在不要求输入密码的情况下运行该脚本。

username ALL=(ALL) NOPASSWD: /path/to/script
Run Code Online (Sandbox Code Playgroud)

  • 不确定是否有人提到过它,但是您必须在编辑 `sudoers` 文件后终止该用户的所有登录会话。 (11认同)
  • 没有为我工作,但谢谢,很高兴知道这存在。也许我的语法错误。 (2认同)
  • 只是为了澄清这里,它不是包含应在 sudoers 文件中指定的“sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql”行的脚本,而是应在playback_delete_data_patch.sh 脚本或您希望该用户和/或其用户指定的任何其他命令脚本能够通过 sudo 运行而无需指定密码。 (2认同)

Jib*_*ers 31

你可以尝试这样的事情:

echo "PASSWORD" | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql
Run Code Online (Sandbox Code Playgroud)

这不是最安全的做法,因为您正在以纯文本形式编写 sudoer 密码。为了使它更安全,您可以创建一个变量并将 sudo 密码读入该变量,然后您可以执行以下命令:

echo $PASSWORD | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql
Run Code Online (Sandbox Code Playgroud)

此外,如果您不介意以 root 身份执行所有命令,您可以使用 简单地执行您的脚本sudo,如前所述。

sudo ./myscript
Run Code Online (Sandbox Code Playgroud)

  • 安全地将密码读入变量:`read -s PASSWORD` (4认同)

Dan*_*Dan 21

这个答案类似于 terdon's answer。我还建议运行主脚本,sudo这样脚本就可以运行,而无需在执行过程中询问用户密码。

但是,如果您想放弃某些命令的 root 权限并以使用 调用命令的实际用户身份运行它们sudo,您可以检查$SUDO_USER变量以找出原始用户。

这是您如何实现这一目标的示例脚本:

#!/bin/bash

# ref: https://askubuntu.com/a/30157/8698
if ! [ $(id -u) = 0 ]; then
   echo "The script need to be run as root." >&2
   exit 1
fi

if [ $SUDO_USER ]; then
    real_user=$SUDO_USER
else
    real_user=$(whoami)
fi

# Commands that you don't want running as root would be invoked
# with: sudo -u $real_user
# So they will be run as the user who invoked the sudo command
# Keep in mind if the user is using a root shell (they're logged in as root),
# then $real_user is actually root
# sudo -u $real_user non-root-command

# Commands that need to be ran with root would be invoked without sudo
# root-command
Run Code Online (Sandbox Code Playgroud)


小智 8

实际上有一种更简单的方法可以做到这一点。为了可移植性,这是我的实现,但可以随意操作它以满足您的需要。

在启动脚本时输入您的 sudo 密码作为参数,捕获它,并在每个提示输入 sudo 密码的命令中回显它。

#!/bin/bash

PW=$1
echo $PW | ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  
./command_wo_sudo.sh <param>
echo $PW | ./other_command_requires_sudo.sh <param>
Run Code Online (Sandbox Code Playgroud)

您可以在脚本启动后添加提示和捕获,如下所示:

echo "enter the sudo password, please"
read PW
Run Code Online (Sandbox Code Playgroud)

但是如果其他人监视节点上运行的内容;可以访问由它创建的日志;或者只是在运行测试时随机查看您的应该,这可能会危及安全。

这也适用于运行需要 yes 才能继续的命令/脚本:

echo $PW | yes | ./install.sh
Run Code Online (Sandbox Code Playgroud)

echo 是对提示的响应,因此您可以使用任何您需要的东西,如果您正在运行其他有进度提示的脚本,则按顺序排列。但是,请确保您知道该顺序,否则可能会发生不好的事情。

  • 在命令前添加一个空格以避免它出现在历史记录中。 (3认同)
  • 如何使用`read`询问用户名/密码:https://ryanstutorials.net/bash-scripting-tutorial/bash-input.php 这应该可以避免这个问题 (2认同)