将输出重定向到文件时,只是我或者Ruby Process#spawn
中是否存在错误? The documentation说:
redirection:
key:
FD : single file descriptor in child process
[FD, FD, ...] : multiple file descriptor in child process
value:
FD : redirect to the file descriptor in parent process
string : redirect to file with open(string, "r" or "w")
[string] : redirect to file with open(string, File::RDONLY)
[string, open_mode] : redirect to file with open(string, open_mode, 0644)
[string, open_mode, perm] : redirect to file with open(string, open_mode, perm)
[:child, FD] : redirect to the redirected file descriptor
:close : close the file descriptor in child process
FD is one of follows
:in : the file descriptor 0 which is the standard input
:out : the file descriptor 1 which is the standard output
:err : the file descriptor 2 which is the standard error
所以我应该能够将密钥设为[:out, :err]
,将值作为表示文件名的字符串,但是:
% ruby -e 'spawn("ps -ef", [:out, :err] => "foo")'
-e:1:in `spawn': No such file or directory - open (Errno::ENOENT)
from -e:1:in `<main>'
(顺便说一句,我已经用2.1.2和2.0.0进行了测试,但似乎没有任何区别。)
如果我第一次创建文件,行为会改变:
% touch foo
% ruby -e 'spawn("ps -ef", [:out, :err] => "foo")'
但是没有任何内容写入文件,从重定向键中删除:err
证明在设置重定向时出现了问题:
% cat foo
% ruby -e 'spawn("ps -ef", [:out] => "foo")' 2>err
% cat err
ps: write error: Bad file descriptor
解决这种奇怪现象并获得我想要的行为相当容易,例如。
% rm -f foo
% ruby -e 'Process.waitpid(spawn("ps -ef", [:out, :err] => ["foo", "w"]))'
% wc foo
503 4422 36470 foo
或
% rm -f foo
% ruby -e 'Process.waitpid(spawn("ps -ef", :out => "foo", :err => :out))'
% wc foo
503 4422 36470 foo
但由于文件明显与实际行为不符,因此我浪费了30分钟,所以我很想知道它是真正的错误还是我的误解。
我怀疑当使用在单个FD
内组合多个Array
的表单时,Ruby会停止尝试自动检测它是否应该在读取时打开FD
或写入模式,只在读取模式下打开。然后,当进程尝试写入它时,这会失败。当您尝试在同一FD
内混合输入/输出Array
时,似乎可以通过Ruby没有任何错误甚至警告来证实这一点:
% yes | head -n3 > foo
% ruby -e 'Process.waitpid(spawn("wc", [:in, :out] => "foo"))'
wc: write error
% cat foo
y
y
y
% yes | head -n3 > foo
% ruby -e 'Process.waitpid(spawn("wc", [:in, :out] => ["foo"]))'
wc: write error
% cat foo
y
y
y
但我确信其他人可以提供更好的解释。