我有一个ruby脚本写入一些输出然后exec
一个命令。该命令希望继承父文件描述符,因为它将从stdin
读取,以某种方式对其进行转换,然后将输出写入stdout
。
这是一个例子
#!/usr/bin/env ruby
puts 'hello from parent'
exec 'tr', '[:lower:]', '[:upper:]'
如果我们直接在shell中运行它,我们会看到两行输出
$ echo 'hello, world!' | ./example.rb
hello from parent
HELLO, WORLD!
但是,如果正在重定向进程的stdout
,则会丢失父进程的输出。
$ echo 'hello, world!' | ./example.rb | cat
HELLO, WORLD!
这是为什么?第一种情况和第二种情况之间的区别是什么?
此外,如果我们在ruby脚本中将exec
更改为system
,则会将两行打印到终端。导致这种行为差异的原因是什么?
仅仅为了比较,一个大致相当的bash脚本似乎没有表现出相同的行为:
#!/bin/bash
echo 'hello from parent'
exec 'tr' '[:lower:]' '[:upper:]'
我们从父母和孩子那里得到输出。
$ echo 'hello, world!' | ./example.sh | cat
hello from parent
HELLO, WORLD!
答案 0 :(得分:2)
听起来像Ruby在exec
的另一个程序之前没有刷新标准输出。您可以明确刷新标准输出。
[STEP 105] # cat example.rb
#!/usr/bin/env ruby
puts 'hello from parent'
$stdout.flush
exec 'tr', '[:lower:]', '[:upper:]'
[STEP 106] # echo 'hello, world!' | ./example.rb | cat
hello from parent
HELLO, WORLD!
[STEP 107] #