Joerg Endrullis
Joerg Endrullis

Reputation: 71

linux pipe with multiple programs asking for user input

I wonder how to create a pipe

program 1 | ... | program N

where multiple of the programs ask for user input. The problem is that | starts the programs in parallel and thus they start reading from the terminal in parallel.

For such cases it would be useful to have a pipe | that starts program (i+1) only after program i has produced some output.

Edit:

Example:

cat /dev/sda | bzip2 | gpg -c | ssh user@host 'cat > backup'

Here both gpg -c as well as ssh ask for a password.

A workaround for this particular example would be the creation of ssh key pairs, but this is not possible on every system, and I was wondering whether there is a general solution. Also gpg allows for the passphrase to be passed as command line argument, but this is not suggested for security reasons.

Upvotes: 6

Views: 3127

Answers (4)

Joerg Endrullis
Joerg Endrullis

Reputation: 71

I am now using:

#!/bin/bash
sudo echo "I am root!"
sudo cat /dev/disk0 | bzip2 | gpg -c | (read -n 1 a; (echo -n "$a"; cat) | ssh user@host 'cat > backup')

The first sudo will prevent the second from asking the password again. As suggested above, the read postpones the starting of ssh. I used -n 1 for read since I don't want to wait for newline, and -n for echo to surpress the newline.

Upvotes: 1

curious_prism
curious_prism

Reputation: 349

I've needed something similar a few times before, where the first command in the pipeline requires a password to be entered, and the next command doesn't automatically cater for this (like the way that less does).

Similar to Igor's response, I find the use of read inside a subshell useful:

cmd1 | ( read; cat - | cmd2 )

Upvotes: 0

bdecaf
bdecaf

Reputation: 4732

for one you can give gpg the password with the --passphrase option.

For ssh the best solution would be to login by key. But if you need to do by password the expect command will be good. Here's a good example: Use expect in bash script to provide password to SSH command

Expect also allows you to have some input - so if you don't want to hardcode your passwords this might be the way to go.

Upvotes: 0

Igor Chubin
Igor Chubin

Reputation: 64563

You can use this construction:

(read a; echo "$a"; cat) > file

For example:

$ (read a; echo "$a"; echo cat is started > /dev/stderr; cat) > file
1
cat is started
2
3

Here 1, 2 and 3 were entered from keyboard; cat is started was written by echo.

Contents of file after execution of the command:

$ cat file
1
2
3

Upvotes: 1

Related Questions