Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

robot:

#!/bin/bash
sudo echo apple
sudo cat << EOF
banana
EOF

command prompt:

$ sudo true
[sudo] password for vb:
$ ./robot
apple
banana
$ ./robot > /dev/null
$ ./robot &> /dev/null
[sudo] password for vb:

Why sudo(1) asks for password when stdout and stderr are redirected?

share|improve this question

It reads from and writes to /dev/tty, which always connects to the current tty/pty.

share|improve this answer
    
This is a security feature to prevent, for example, brute force attacks. – Andrew Lambert Apr 24 '11 at 23:20
    
Thanks. It seems that "sudo -A" is the only choice to circumvent this. – vbarbarosh Apr 24 '11 at 23:42
1  
@Amazed: I doubt that. A bruteforcer process could allocate a pty in two lines of code. It seems to me that it's just to allow the user to redirect all output and not have it messed up by the password prompt. – grawity Apr 25 '11 at 15:31

Sudo remembers your password (your authentication) for some time so you do not have to enter the password for multiple commands in quick succession.

The duration is controlled by the timestamp_timeout statement in the /etc/sudoers file. Read man sudoers for more information.

More interessting is the question how your authentication is remembered. Everytime you use sudo, sudo will create a file in the directory /var/run/sudo/username (Ubuntu 10.04). The filename is taken from your current terminal (or tty). That means sudo remembers your authentication on a per terminal basis. If you switch to another terminal, sudo will not remember that you just used sudo on the previous terminal.

Demonstration:

Use sudo:

$ sudo echo foo
[sudo] password for lesmana: 
foo

See file created in /var/run/sudo/username:

$ sudo ls -l /var/run/sudo/lesmana
total 0
-rw------- 1 root lesmana  0 2011-04-25 16:56 1

Note that this sudo did not ask for password. The file is named 1 because I ran the sudo command from tty (or pts) number 1. use the tty command to see your tty name.

$ tty
/dev/pts/1

Now switch to another terminal:

$ tty
/dev/pts/2

Use sudo in this terminal.

$ sudo echo bar
[sudo] password for lesmana: 
bar

Note that it asks for a password.

See file created in /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

Now switch to a virtual console.

$ tty
/dev/tty/1

Use sudo:

$ sudo echo baz
[sudo] password for lesmana: 
baz

See file created in /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

Now let's try that using your shell script. I used the same robot script as in the question text.

$ ./robot
apple
banana

No password prompt because I used the first terminal in which sudo still remembers my password.

See the file updated in /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

Now let's try the script with redirection:

$ ./robot > foo
[sudo] password for lesmana:

Note that sudo asked for password.

Check /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

See that unknown file. For whatever reason sudo is no longer able to determine the terminal when executed in a script with redirected streams. That is why sudo asks you for your password.

Note that on your system sudo asked for password only after redirecting both stdout and stderr. On my system (ubuntu 10.04) sudo asked for password when I redirected stdout. I have no idea why there is this difference.

Note also that you can make sudo forget your authentication immediately with the command sudo -k. This will only forget the authentication for the terminal where the command was issued.

share|improve this answer
    
I use Debian 6.0.1. On this system the directory where sudo(1) stores passwords is /var/lib/sudo/vb/, and I notice no "tty?" nor "unknown" files here. Only "0", "1", "2", and "3". I never heard about tty(1) previously so I tried the following: 1) add "tty" to the robot script; 2) ./robot &> tempfile; 3) cat tempfile. The strange thing was that tempfile contain "/dev/pts/3" line. So, why "sudo is no longer able to determine the terminal when executed in a script with redirected streams."? Is it a bug? – vbarbarosh Apr 26 '11 at 16:31
    
@vladimirbarbarosh: I also added a tty line in the robot script, and on my system it was also able to correctly name the tty. I have no idea why sudo is not able to determine that on my system. I also have no idea why sudo seems to have the correct tty name on your sysem, yet still asks for an password as if it a differnet tty. Perhaps it is a bug, I just don't know whether it is on my system, or on your system, or on both. – lesmana Apr 27 '11 at 18:56
    
The problem lies here: sudo &> /dev/null < /dev/null. Everything ok for sudo &> /dev/null. I ask the question on sudo maillist. As soon as I found the answer I will post it here. Just now I consider this as a bug. – vbarbarosh Apr 28 '11 at 14:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.