-
Notifications
You must be signed in to change notification settings - Fork 0
Capture subprocess output using a non‐standard file descriptor
James Couball edited this page Mar 8, 2025
·
1 revision
This script spawns a subprocess, redirecting the output from file descriptor 3 in the child process the file "output.txt". The parent passes the redirected file descriptor to the child process in the environment variable CUSTOM_FD
.
The child process opens the file descriptor and writes the string "Child process writing to file descriptor 3... DONE\n" using the file descriptor.
The parent process checks the file "output.txt" to make it contains the output from the child process.
require 'fileutils'
require 'pp'
def ruby_command(code)
@ruby_path ||=
if Gem.win_platform?
`where ruby`.chomp
else
`which ruby`.chomp
end
[@ruby_path, '-e', code]
end
# This is the spawned script:
child_script = <<~SCRIPT
custom_fd = ENV["CUSTOM_FD"].to_i
custom_io = IO.new(custom_fd)
custom_io.print "Child process writing to file descriptor \#{custom_fd}..."
custom_io.puts "DONE"
custom_io.close
SCRIPT
command = ruby_command(child_script)
child_file_descriptor = 3
capture_filepath = 'output.txt'
status = nil
File.open(capture_filepath, 'w') do |capture_file|
_pid, status = Process.wait2(
Process.spawn(
{ 'CUSTOM_FD' => child_file_descriptor.to_s },
*command,
child_file_descriptor => capture_file.fileno
)
)
end
puts <<~RESULT
Status: #{status}
Expected contexts of #{capture_filepath}: "Child process writing to file descriptor 3...DONE\\n"
Actual context of #{capture_filepath}: #{File.read(capture_filepath).pretty_inspect}
RESULT