ruby脚本:exec后父输出丢失

时间:2018-02-11 18:31:41

标签: ruby bash process io-redirection

我有一个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!

1 个答案:

答案 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] #