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
потому что я запустил команду sudo с номера tty (или pts) 1. Используйте команду 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
Теперь давайте попробуем это с помощью вашего сценария оболочки. Я использовал тот же скрипт робота, что и в тексте вопроса.
$ ./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) sudo попросил пароль, когда я перенаправил стандартный вывод. Я понятия не имею, почему есть такая разница.
Также обратите внимание, что вы можете заставить sudo немедленно забыть свою аутентификацию с помощью команды sudo -k
. Это забудет только аутентификацию для терминала, на котором была выполнена команда.