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.
对于这种情况,有一个管道是有用的只有在程序i产生了一些输出后才启动程序(i + 1)。
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.
这里gpg -c和ssh都要求输入密码。
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.
这个特定示例的解决方法是创建ssh密钥对,但这在每个系统上都不可能,我想知道是否有一般解决方案。此外,gpg允许将密码短语作为命令行参数传递,但出于安全原因,不建议这样做。
4 个解决方案
#1
1
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.
这里从键盘输入1,2和3;猫开始是由echo写的。
Contents of file
after execution of the command:
执行命令后的文件内容:
$ cat file
1
2
3
#2
1
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.
第一个sudo将阻止第二个再次询问密码。如上所述,读取推迟了ssh的开始。我使用-n 1进行读取,因为我不想等待换行符,并且-n for echo来压缩换行符。
#3
0
for one you can give gpg the password with the --passphrase
option.
您可以使用--passphrase选项为gpg提供密码。
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
对于ssh,最好的解决方案是按键登录。但是如果你需要通过密码来执行expect命令会很好。这是一个很好的例子:在bash脚本中使用expect为SSH命令提供密码
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.
期望也允许你有一些输入 - 所以如果你不想硬编码你的密码,这可能是你要走的路。
#4
0
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:
与Igor的响应类似,我发现在子shell中使用read非常有用:
cmd1 | ( read; cat - | cmd2 )
#1
1
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.
这里从键盘输入1,2和3;猫开始是由echo写的。
Contents of file
after execution of the command:
执行命令后的文件内容:
$ cat file
1
2
3
#2
1
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.
第一个sudo将阻止第二个再次询问密码。如上所述,读取推迟了ssh的开始。我使用-n 1进行读取,因为我不想等待换行符,并且-n for echo来压缩换行符。
#3
0
for one you can give gpg the password with the --passphrase
option.
您可以使用--passphrase选项为gpg提供密码。
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
对于ssh,最好的解决方案是按键登录。但是如果你需要通过密码来执行expect命令会很好。这是一个很好的例子:在bash脚本中使用expect为SSH命令提供密码
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.
期望也允许你有一些输入 - 所以如果你不想硬编码你的密码,这可能是你要走的路。
#4
0
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:
与Igor的响应类似,我发现在子shell中使用read非常有用:
cmd1 | ( read; cat - | cmd2 )