管道不写入stdout的程序的输出

时间:2014-06-26 14:55:28

标签: bash

当输入程序没有写入stdout时,我正在寻找使用管道的最佳方法。具体来说,我想将objcopy导入hexdump,就像这样

objcopy -I ifmt -O binary ifile - | hexdump -C

但objcopy不接受' - '作为一个文件,意思是'写入stdout',就像某些程序那样。

我正在做的那一刻

objcopy -I ifmt -O binary ifile tmpfile; hexdump -C tmpfile; rm tmpfile

但是想知道是否有更好的方法。

我在cygwin上使用bash 4.1.10。

2 个答案:

答案 0 :(得分:2)

我写了一篇评论规定了流程替换,但它不适用于objcopy,因为objcopy会尝试打开可搜索文件(因为它可能需要来回移动)文件)。

简而言之:objcopy无法以stdout的形式写入流,这就是为什么其输出必须是可以搜索的文件的原因。您的解决方案很可能是唯一合理的可能性。


回答你的问题

  

当输入程序没有写入stdout时,我正在寻找使用管道的最佳方法

以更一般的方式(但不适用于objcopy或任何需要查找文件的命令),在Bash中,您可以使用进程替换:如果mycommand采用参数这是一个输出文件,并且不接受-作为标准输出,并且默认情况下不会写入标准输出,您可以将其用作:

mycommand >(cat)

或者如果您想通过它,例如hexdump -C

mycommand >(hexdump -C)

这样,mycommand将看到/dev/fd/42形式的参数(其中42可能不同),并且可以打开它进行写入,就好像它是常规文件(但不是可寻的),hexdump将在标准输入上写入数据。

您可以像这样试验流程替换:调用以下脚本mycommand

#!/bin/bash

if [[ $1 ]]; then
    echo "Hi, this is mycommand, and I was called with first argument: \`$1'"
    echo "I'm outputting this to the file given as argument" > "$1"
else
    echo >&2 "Please provide an argument (file to write to)"
    exit 1
fi

此脚本确保您提供非空参数(否则显示错误消息),将此参数输出到标准输出,并在文件中添加一个小行作为参数。

然后chmod +x mycommand并使用它:

$ ./mycommand
Please provide an argument (file to write to)
$ ./mycommand -
Hi, this is mycommand, and I was called with first argument: `-'
$ ls
- mycommand
$ rm ./-
$ ./mycommand >(cat)
Hi, this is mycommand, and I was called with first argument: `/dev/fd/63'
I'm outputting this to the file given as argument
$ ./mycommand >(tr -d e)
Hi, this is mycommand, and I was called with first argument: `/dev/fd/63'
I'm outputting this to th fil givn as argumnt
$ ./mycommand >(hexdump -C)
Hi, this is mycommand, and I was called with first argument: `/dev/fd/63'
00000000  49 27 6d 20 6f 75 74 70  75 74 74 69 6e 67 20 74  |I'm outputting t|
00000010  68 69 73 20 74 6f 20 74  68 65 20 66 69 6c 65 20  |his to the file |
00000020  67 69 76 65 6e 20 61 73  20 61 72 67 75 6d 65 6e  |given as argumen|
00000030  74 0a                                             |t.|
00000032
$ ./mycommand >(cat) > /dev/null
I'm outputting this to the file given as argument

答案 1 :(得分:1)

实际上,您可以使用zsh

(){objcopy -O binary -j .text <input file> $1; cat $1} =(touch -c .) | hexdump -C

说明

  • =()是zsh进程替换,它支持所需的seek属性。
  • 函数体内的
  • $1指的是=(touch -c .)创建的文件。

    • 请注意,cmd“ touch -c .
    • -c---no-create,因此该命令本身不执行任何操作,我们只是将其用于副作用=(),它是zsh创建的包含以下内容的临时文件: touch -c .的输出(无内容),并在命令完成后删除。
  • (){}是匿名函数语法,它使=()创建的文件在函数体内保持足够长的时间,以至于cat变成stdout。 / p>