pipe password to `sudo` and other data to `sudo`ed command

19,987

Solution 1

This will do:

{ echo 'mypassword'; echo 'some text'; } | sudo -k -S tee -a /etc/test.txt &>/dev/null

The point is sudo and tee use the same stdin, so both will read from the same source. We should put "mypassword" + "\n" just before anything we want pass to tee.

Explaining the command:

  • The curly braces groups command. We can look at {...} as one command. Whatever is in {...} writes to the pipe.
  • echo 'mypassword' will write "mypassword\n" to the pipe. This is read by sudo later.
  • echo 'some text' write "some text\n" to the pipe. This is what will reach tee at the end.
  • sudo -k -S reads password from its stdin, which is the pipe, until it reaches "\n". so "mypassword\n" will be consumed here. The -k switch is to make sure sudo prompt for a password and ignore user's cached credential if it's used recently.
  • tee reads from stdin and it gets whatever left in it, "some text\n".

PS: About I/O redirection: Yes you are right, 1>filename is identical to >filename. They both redirect stdout to filename. Also 0<filename and <filename are identical, both redirect stdin.

Solution 2

I couldn't put it in a comment, but note that you can combine the -k option with the already existing sudo command, i.e., instead of using

sudo -k && echo 'some text' | { echo 'mypassword'; cat -; } | sudo -S tee -a /etc/test.txt &>/dev/null

you can directly put the -k in the original sudo. It might even be "safer":

echo 'some text' | { echo 'mypassword'; cat -; } | sudo -k -S tee -a /etc/test.txt &>/dev/null

Solution 3

This is a bit late but I find this to work well:

sudo -k && echo -e "password\ntext" | sudo -S tee file > /dev/null 2>&1

This does not require multiple pipes and is simpler to understand.

> /dev/null 2>&1

This redirects all output including the one asking for password to /dev/null.

Share:
19,987

Related videos on Youtube

Anthony Webber
Author by

Anthony Webber

Updated on September 18, 2022

Comments

  • Anthony Webber
    Anthony Webber almost 2 years

    Both of these commands work: (note the -S in sudo tells sudo to read the password from stdin).

    echo 'mypassword' | sudo -S tee -a /etc/test.txt &> /dev/null
    echo -e '\nsome\nmore\ntext' | sudo tee -a /etc/test.txt &> /dev/null
    

    Now I would like to combine the two, i.e. achieve everything in just one line. But, of course, something like this doesn't work:

    echo -e '\nsome\nmore\ntext' | echo 'mypassword' | sudo -S tee -a /etc/test.txt &> /dev/null
    

    What would work? Thanks:) - Loady

    PS: Minor unrelated question: is 1> identical to > ? I believe they are..

    • Q23
      Q23 almost 7 years
      Yes, the 1 in 1> is implied.
    • Q23
      Q23 almost 7 years
      And if you want to run everything on one line, can't you just command1 && command2?
    • Anthony Webber
      Anthony Webber almost 7 years
      @Q23 echo 'mypassword' | sudo -S && echo -e '\nsome\nmore\ntext' | tee -a /etc/test.txt &> /dev/null doesn't work..
    • Martin von Wittich
      Martin von Wittich almost 7 years
      This sounds like an extremely bad idea. What are you trying to accomplish? Why not just add a NOPASSWD entry to your sudoers file?
    • Anthony Webber
      Anthony Webber almost 7 years
      @Martin I'm trying to direct 'mypassword' to sudo, and \nsome\nmore\ntext to tee
    • Martin von Wittich
      Martin von Wittich almost 7 years
      @AnthonyWebber yes, that I understood, but why? Do you need call sudo from a script or a cronjob or something, so that it has to run non-interactively? Then the NOPASSWD option is probably far safer and less complicated than putting the password into a script and trying to pipe it into sudo.
  • Navid Ht
    Navid Ht about 4 years
    I edited my answer, thanks.
  • Diego Bandeira
    Diego Bandeira over 2 years
    This way the password could be seen by another user that runs ps aux. Is that correct? In this same direction, this oneliner echo "some text" | sudo -k -S <<< $PASSWORD tee /etc/test.txt would work, or does it falls into the same problem of having only one STDIN?
  • Navid Ht
    Navid Ht over 2 years
    @DiegoBandeira I tested your suggestion using here strings. The answer is yes and no! It doesn't work in bash, as I expected, but works in zsh.