Lot*_*ney 32 linux command-line shell bash process-substitution
有时,过程替换不会按预期工作。下面是一个例子:
输入:
gcc <(echo 'int main(){return 0;}')
Run Code Online (Sandbox Code Playgroud)
输出:
/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
输入:
但是当与不同的命令一起使用时,它会按预期工作:
grep main <(echo 'int main(){return 0;}')
Run Code Online (Sandbox Code Playgroud)
输出:
int main(){return 0;}
Run Code Online (Sandbox Code Playgroud)
我注意到与其他命令类似的失败(即期望来自进程替换的文件的命令不能使用/dev/fd/63
或类似)。这次失败gcc
只是最近的一次。是否有一些我应该注意的一般规则来确定进程替换何时会以这种方式失败并且不应该使用?
我在 Ubuntu 12.04 上使用这个 BASH 版本(我也在 arch 和 debian 中看到过这个):
GNU bash,版本 4.3.11(1)-release (i686-pc-linux-gnu)
Cel*_*ada 37
进程替换会生成一个特殊文件(如/dev/fd/63
您的示例中所示),其行为类似于命名管道的读取端。该文件可以打开和读取,但不能写入,也不能搜索。
将参数视为纯流的命令可以工作,而期望在给定(或写入)文件中查找的命令将不起作用。可以工作的命令类型通常被认为是过滤器:cat
, grep
, sed
, gzip
, awk
, 等等... 一个不能工作的命令的例子是类似编辑器vi
或类似的文件操作mv
。
gcc
希望能够对其输入文件执行随机访问以检测它们是用什么语言编写的。 如果您提供gcc
有关输入文件语言的提示,则很高兴流式传输文件:
gcc -x c <(echo 'int main(){return 0;}')
Run Code Online (Sandbox Code Playgroud)
没有进程替换的更简单更直接的形式也适用:
echo 'int main(){return 0;}' | gcc -x c -
Run Code Online (Sandbox Code Playgroud)
请注意,这不是特定于bash
. 所有支持进程替换的 shell 的行为方式都相同。