2012-08-02 52 views
6

的Linux管我不知道如何创建一个管道与多个程序要求用户输入

program 1 | ... | program N 

在程序的多个要求用户输入。问题是|并行启动程序,因此它们开始从终端并行读取。

对于这样的情况,只有在程序i产生了一些输出后,才有一个管道|启动程序(i + 1)会很有用。

编辑:

例子:

cat /dev/sda | bzip2 | gpg -c | ssh [email protected] 'cat > backup' 

这里既有gpg -c以及ssh询问密码。

对于这个特定的例子,一个解决方法是创建ssh密钥对,但这在每个系统上都是不可能的,我想知道是否有一个通用的解决方案。 此外,gpg允许将口令作为命令行参数传递,但出于安全原因不建议这样做。

+1

一旦一个程序连接到一个管道,它从另一个程序,而不是用户的输入。你确定你想要一个管道吗?我无法真正想到一个程序,它们都需要用户输入*和*从标准输入读取。 – chepner 2012-08-02 22:32:23

+0

不是一个答案,而是一个可能指向正确方向的想法:是否可以在每个程序周围包含代码,以检查特定字符串的输出,更新一次发现的标志并让其他调用循环直到前一个程序的标志为止更新,然后让他们跑? – JohnLBevan 2012-08-02 22:53:00

+2

显示这种情况的具体示例。一个程序可以从'stdin'和'/ dev/tty'中读取,但这是不常见的。 – 2012-08-03 01:01:44

回答

1

您可以使用此结构:

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

例如:

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

这里123从键盘输入; cat is started是由echo编写的。

file内容的命令执行后:

$ cat file 
1 
2 
3 
0

一个你可以给与--passphrase选项GPG密码。

对于ssh 最佳解决方案将通过密钥登录。但如果你需要通过密码来做expect命令将会很好。这里有一个很好的例子:Use expect in bash script to provide password to SSH command

期望也允许你有一些输入 - 所以如果你不想硬编码你的密码这可能是一条路。

1

我现在使用:

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

第一sudo将防止第二再次询问密码。如上所示,read推迟ssh的开始。我使用-n 1代替read,因为我不想等换行符,而-n代替echo来压制换行符。

+1

'sudo -v'会延长超时时间,如果你还没有验证,提示输入密码。这可以让你避免必须拿出一个无关的命令('echo“I root!”')来运行。 – chepner 2013-02-26 17:26:52

0

我以前需要类似的东西,在管道中的第一个命令需要输入密码,并且下一个命令不会自动迎合此(类似于less所做的那样)。

伊戈尔的反应类似,我发现使用的有用子shell里面写着:

cmd1 | (read; cat - | cmd2) 
相关问题