linux管道有多个程序要求用户输入

时间:2022-11-30 16:50:43

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 )