【问题标题】:How do I redirect stdin/stdout when I have a sequence of commands in Bash?当我在 Bash 中有一系列命令时,如何重定向标准输入/标准输出?
【发布时间】:2011-02-08 16:41:19
【问题描述】:

我目前正在执行一个 Bash 命令(通过 Python 的 subprocess.Popen),该命令从 stdin 读取,执行某些操作并输出到 stdout。大致如下:

pid = subprocess.Popen( ["-c", "cmd1 | cmd2"],
                       stdin = subprocess.PIPE, 
                       stdout = subprocess.PIPE, 
                       shell =True )
output_data = pid.communicate( "input data\n" )

现在,我想做的是改变它以在同一个子shell中执行另一个命令,这将在下一个命令执行之前改变状态,所以我的shell命令行现在(概念上)是:

cmd0; cmd1 | cmd2

在这种情况下,有什么方法可以将输入发送到cmd1 而不是cmd0?我假设输出将包括cmd0 的输出(将为空),然后是cmd2 的输出。

cmd0 实际上不应该从stdin 中读取任何内容,在这种情况下会有所不同吗?

我知道这可能只是一种愚蠢的做法,我正在尝试修补cmd0 而不会太显着地改变其他代码。也就是说,如果有更清洁的方法来解决这个问题,我愿意接受建议。

【问题讨论】:

  • 很难理解你在问什么。也许举一个具体的例子,或者更好的是,描述你正在尝试做的事情。

标签: python bash pipe subprocess


【解决方案1】:

好的,我想我可以将stdin文件描述符复制到一个临时的,关闭它,运行cmd0,然后在运行cmd1之前恢复它:

exec 0>&3; exec 0<&-; cmd0 ; exec 3>&0 ; cmd1 | cmd2

不确定是否可以通过这种方式重定向stdin,目前无法测试。

http://tldp.org/LDP/abs/html/io-redirection.html

http://tldp.org/LDP/abs/html/x17601.html

【讨论】:

  • 好的,考虑到人们给出的其他答案,这可能没有必要(即使它会起作用)。
【解决方案2】:

在子 shell 中执行 cmd0cmd1 并将 /dev/null 重定向为 cmd0 的 stdin

(cmd0 </dev/null; cmd1) | cmd2

【讨论】:

  • +1:虽然 OP 说 cmd0 不会触及标准输入,但还是安全的!
【解决方案3】:

我认为你不应该做任何特别的事情。如果 cmd0 不接触标准输入,那么它对于 cmd1 将是完整的。自己试试吧:

ls | ( echo "foo"; sed 's/^/input: /')

(使用ls作为任意命令为管道生成几行输入)

当然,到 cmd2 的附加管道也不影响输入。

【讨论】:

  • 好的,这看起来不错,这是我需要知道的。有空我会试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-24
  • 1970-01-01
  • 2018-08-12
  • 2012-05-11
  • 2022-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多