机器人:
#!/bin/bash
sudo echo apple
sudo cat << EOF
banana
EOF
命令提示符:
$ sudo true
[sudo] password for vb:
$ ./robot
apple
banana
$ ./robot > /dev/null
$ ./robot &> /dev/null
[sudo] password for vb:
为什么当 stdout 和 stderr 重定向时 sudo(1) 会要求输入密码?
答案1
Sudo 会在一段时间内记住您的密码(您的身份验证),因此您不必快速连续地输入多个命令的密码。
timestamp_timeout
持续时间由文件中的语句控制/etc/sudoers
。阅读man sudoers
更多信息。
更有趣的是这个问题如何您的身份验证会被记住。每次使用 sudo 时,sudo 都会在目录中创建一个文件/var/run/sudo/username
(Ubuntu 10.04)。文件名取自您当前的终端(或 tty)。这意味着 sudo 会在每个终端上记住您的身份验证。如果您切换到另一个终端,sudo 将不会记住您刚刚在上一个终端上使用过 sudo。
示范:
使用 sudo:
$ sudo echo foo
[sudo] password for lesmana:
foo
查看创建的文件/var/run/sudo/username
:
$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana 0 2011-04-25 16:56 1
请注意,此 sudo 不要求输入密码。文件之所以被命名,1
是因为我从 tty(或 pts)1 号运行了 sudo 命令。使用该tty
命令查看您的 tty 名称。
$ tty
/dev/pts/1
现在切换到另一个终端:
$ tty
/dev/pts/2
在此终端中使用 sudo。
$ sudo echo bar
[sudo] password for lesmana:
bar
请注意,它要求输入密码。
查看创建的文件/var/run/sudo/username
:
$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana 0 2011-04-25 16:56 1
-rw------- 1 root lesmana 0 2011-04-25 16:57 2 # <-- new
现在切换到虚拟控制台。
$ tty
/dev/tty/1
使用 sudo:
$ sudo echo baz
[sudo] password for lesmana:
baz
查看创建的文件/var/run/sudo/username
:
$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana 0 2011-04-25 16:56 1
-rw------- 1 root lesmana 0 2011-04-25 16:57 2
-rw------- 1 root lesmana 0 2011-04-25 16:58 tty1 # <-- new
现在让我们使用您的 shell 脚本尝试一下。我使用了与问题文本中相同的机器人脚本。
$ ./robot
apple
banana
没有密码提示,因为我使用了第一个 sudo 仍然记得我的密码的终端。
请参阅更新的文件/var/run/sudo/username
:
$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana 0 2011-04-25 17:01 1 # <-- timestamp update
-rw------- 1 root lesmana 0 2011-04-25 16:57 2
-rw------- 1 root lesmana 0 2011-04-25 16:58 tty1
现在让我们尝试使用重定向的脚本:
$ ./robot > foo
[sudo] password for lesmana:
请注意,sudo 要求输入密码。
查看/var/run/sudo/username
:
$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana 0 2011-04-25 17:01 1
-rw------- 1 root lesmana 0 2011-04-25 16:57 2
-rw------- 1 root lesmana 0 2011-04-25 16:58 tty1
-rw------- 1 root lesmana 0 2011-04-25 17:02 unknown # <-- new
请参阅该unknown
文件。无论出于何种原因,sudo 在具有重定向流的脚本中执行时都无法再确定终端。这就是 sudo 要求您输入密码的原因。
请注意,在您的系统上,sudo 仅在重定向 stdout 和 stderr 后才要求输入密码。在我的系统 (ubuntu 10.04) 上,当我重定向 stdout 时,sudo 要求输入密码。我不知道为什么会有这种差异。
还要注意,你可以使用命令让 sudo 立即忘记你的身份验证sudo -k
。这只会忘记发出命令的终端的身份验证。
答案2
它从 读取并写入/dev/tty
,它始终连接到当前 tty/pty。