我有一个使用过几次的 bash 脚本sudo
。不过它有几个奇怪的地方。
- 在我为上一条命令输入密码几秒钟后,它会要求我输入密码。
- 当我第二次输入密码时,密码会显示在屏幕上。
以下是脚本的相关部分。
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