sudo 在 bash 脚本中显示输入的密码

sudo 在 bash 脚本中显示输入的密码

我有一个使用过几次的 bash 脚本sudo。不过它有几个奇怪的地方。

  1. 在我为上一条命令输入密码几秒钟后,它会要求我输入密码。
  2. 当我第二次输入密码时,密码会显示在屏幕上。

以下是脚本的相关部分。

sudo service apache2 stop
drush sql-dump --root="$SITE_DIR" --structure-tables-key=svn --ordered-dump | grep -iv 'dump completed on' | sudo tee "$DB_DIR/${SITE_NAME}.sql" > /dev/null
sudo svn diff "$DB_DIR" | less
sudo svn commit -m "$MESSAGE" "$DB_DIR"
sudo service apache2 start

第一个密码是用来停止 Apache 的,它按预期工作。如上所述,它sudo tee不“记住”我有提升的权限,再次要求输入密码,将其回显到屏幕上。鉴于这tee都是关于回显到屏幕上的,我使用了一些具有的简单脚本进行了一些尝试| sudo tee,它们都按预期工作。

编辑: 我查看了drush命令本身,它是一个使用 调用 PHP 的 bash 文件exec。这听起来很有潜力 - 有什么想法吗?以下是 中的一行drush

exec php $SCRIPT_PATH --php=`which php` "$@"

编辑2: 正在寻找与 Ruby 脚本有关的内容,看到了这个帖子有关 serverfault 脚本中的提升权限。

答案1

我可以建议另一种解决方案吗?停止sudo在 bash 脚本中使用,而是使用提升的权限运行整个脚本。

您可以轻松检查脚本是否以 root 身份运行:

if [[ $(/usr/bin/id -u) -ne 0 ]]; then
    echo "$0 must be run as root"
    exit 1
fi

取自这个问题

答案2

你能重新检查一下你的sudo版本吗?
我在当前 sudo 手册

-A

通常,如果 sudo 需要密码,它会从当前终端读取密码。如果指定了 -A(askpass)选项,则会执行(可能是图形化的)帮助程序来读取用户的密码并将密码输出到标准输出。如果设置了 SUDO_ASKPASS 环境变量,则指定辅助程序的路径。否则,将使用 sudoers(5) 中 askpass 选项指定的值。

和,

SUDO_ASKPASS

如果没有可用的终端或者指定了 -A 选项,则指定用于读取密码的辅助程序的路径。

不记得以前读过或者用过这个...

答案3

男人8须藤例子:

列出 /home 分区中的目录使用情况。请注意,这将在子 shell 中运行命令,以使 cd 和文件重定向正常工作。

$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"

我不知道你用 tee 进行了什么“测试”,但简单的情况是:

$ sudo id | sudo tee /tmp/junk

同时提示输入两个密码,然后它们都争夺输入队列,所以都没有接受密码(并且它们搞乱了线路stty纪律,所以输入的字符会被回显)。

更新:哦,你想知道为什么 sudo 不适用于管道吗?因为 shell 必须分叉管道的子进程,每个子进程都继承父 shell 的上下文。就 shell 而言,它sudo只是一个命令,它在提升权限的上下文中运行其参数,而不会“流”到管道中。作为一组命令,管道可以读作

drush sql-dump > pipe ;  ( grep < pipe  ;  ( sudo tee file < pipe ) )

这是对正在发生事情的更精确的模型。

答案4

你也可以考虑一些简单的事情,比如为你想要读取的输出创建一个 fifo 或“管道”

`mkfifo -m 600 /path/to/fifo` 

man mkfifo 了解更多信息。您的代码现在将如下所示:

sudo service apache2 stop 
#this will be visible and you can type in your password
stty -echo
# this will now remove echoing of characters to the screen
drush sql-dump --root="$SITE_DIR" --structure-tables-key=svn --ordered-dump | grep -iv 'dump completed on' | sudo tee "$DB_DIR/${SITE_NAME}.sql" > /dev/null
# as you are again looking for visible output, i would use the fifo here
sudo svn diff "$DB_DIR" \> /path/to/fifo &
sleep 4 # or longer
tail /path/to/fifo
sudo svn commit -m "$MESSAGE" "$DB_DIR"
sudo service apache2 start
stty echo

相关内容