Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

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

I have this compound command working for the root user and have been jumping through hoops trying to get it to work for a sudoer (rsa keys, echoing the pwd, supressing tty etc) but I can't seem to get past this final hurdle:

$ git archive --format=tar master | gzip -9c | ssh -t -t user1@xxx.xx.xx.xx "ec
ho password123 | sudo -S tar --directory=test -xvzf -"


tcgetattr: Not a character device
[sudo] password for user1:
gzip: stdin: unexpected end of file
tar: Child returned status 1
tar: Error is not recoverable: exiting now
Connection to xxx.xx.xx.xx closed.

gzip: stdout: Invalid argument

Any ideas??


share|improve this question
Can you update your sudo configuration to be passwordless? The fact that both sudo, and tar are trying to get data from stdin is a problem. – Zoredache Jul 25 '13 at 23:27
The fact that gzip reports an error related to stdin makes me wonder what happens if you do just git archive --format=tar master | gzip -9c > /dev/null. If that fails, work on that before you try the fancy remote stuff. – Scott Jul 26 '13 at 0:20
And why do you believe that you need the -t –t? – Scott Jul 26 '13 at 0:34
OK, the tcgetattr: Not a character device message may justify the idea that -t -t would be helpful. But, if you’re still getting that tcgetattr warning, that suggests that the -t -t isn’t helping. – Scott Jul 26 '13 at 16:46

Zoredache is right: the overloading of stdin is a problem.  It might help if you separated the data streams by changing the quoted remote command (after the xx) to something like

"exec 4<&0; echo password123 | sudo -S tar --directory=test -xvzf - <&4"

This should take the stdin to the remote command –– which is the stdin to the ssh; i.e., the output from gzip –– and shuffle it over to file descriptor 4.  Then you echo the password and pipe it into sudo –S, and then run the tar with input from file descriptor 4, which is the saved data stream (the output from gzip).

OK, that probably won’t work, because sudo and tar are too tightly coupled.  So, instead, try

"exec 4<&0; echo password123 | sudo -S sh –c \"tar --directory=test -xvzf - <&4\""

That should provide the extra layer of separation between sudo and tar to allow sudo to read the password and tar to read the output from gzip.

OK, it comes back to me that the file descriptors numbered 3 and higher in the shell are not really the file descriptors with those numbers; they are just arbitrary identifiers used within the shell.  So they don’t transfer from one shell instance to another.  So let’s give the crank another turn, and try

'myfifo=/tmp/myfifo.$$; mkfifo "$myfifo"; cat > "$myfifo"& sleep 1; echo password123 | sudo -S sh –c "tar --directory=test -xvzf - < \"$myfifo\""; rm "$myfifo"'

I put the entire remote command into single quotes so none of the dollar signs would be interpreted locally.  I may have quoted more than I really needed to.  The sleep 1 is to decrease the probability of a race condition where the tar starts reading from the FIFO before the cat starts writing to it.

share|improve this answer
wow, thanks! it is definitely getting closer, but there appears to be a problem with the file descriptor... is the format correct? tcgetattr: Not a character device [sudo] password for user1: sh: 4: Bad file descriptor Connection to xxx.xx.xx.xx closed. gzip: stdout: Invalid argument – user240880 Jul 26 '13 at 12:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .