如何将 Ruby 的 STDIN 传递给 Open3.popen3 调用的外部程序?
How to pass Ruby's STDIN to an external program called by Open3.popen3?
我想从 Ruby 脚本调用 ffmpeg,让我们调用 "vpipe",我希望这个 Ruby 脚本充当命令之类的过滤器:从中获取输入管道。它的唯一目的是 select 第一个音频流并删除章节数据(如果存在):
#!/usr/bin/ruby
require "open3"
output_file=ARGV[0]
cmd=%Q{ffmpeg -y -i - -map 0:v -map 0:a -c:v copy -c:a:0 copy -map_chapters -1 #{output_file}}
Open3.popen3(cmd,:stdin_data=>STDIN)
那么我想这样调用我的程序:
curl http://www.example.com/video.wmv | vpipe processed.wmv
不幸的是,它不起作用,因为 popen3 没有像 :stdin_data 这样的选项。我也试过 Open3.capture3 可以接受这个论点,但后来我从 curl 收到错误消息:"Failed writing body".
您错过了 popen3
的一个关键功能,那就是它会为您提供句柄,您可以随心所欲地使用它们:
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
# Use stdin, stdout, stderr as you wish.
end
当您的程序位于管道命令的下游时,其 STDIN 将提供前一个命令的输出。
当您使用 Open3.popen3
时,您可以完全控制分叉进程' STDIN
、STDOUT
、STDERR
。您需要手动为它提供所需的数据,并根据需要使用输出。
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
# consume outputs in STDOUT and STDERR, otherwise the ffmpeg process may be blocked if it produces a lot of outputs
Thread.new do
while stdout.read
end
end
Thread.new do
while stderr.read
end
end
while data = STDIN.read(64) # read output of the upstream command
stdin.write(data) # manually pipe it to the ffmpeg command
end
wait_thr.join
end
如果 "vpipe" 做的最后一件事是调用另一个命令,并且您想不加修改地传递 stdin、stdout 和 stderr,那么使用 Open3.popen3
就是一种浪费。请改用 exec
!这很容易。
我想从 Ruby 脚本调用 ffmpeg,让我们调用 "vpipe",我希望这个 Ruby 脚本充当命令之类的过滤器:从中获取输入管道。它的唯一目的是 select 第一个音频流并删除章节数据(如果存在):
#!/usr/bin/ruby
require "open3"
output_file=ARGV[0]
cmd=%Q{ffmpeg -y -i - -map 0:v -map 0:a -c:v copy -c:a:0 copy -map_chapters -1 #{output_file}}
Open3.popen3(cmd,:stdin_data=>STDIN)
那么我想这样调用我的程序:
curl http://www.example.com/video.wmv | vpipe processed.wmv
不幸的是,它不起作用,因为 popen3 没有像 :stdin_data 这样的选项。我也试过 Open3.capture3 可以接受这个论点,但后来我从 curl 收到错误消息:"Failed writing body".
您错过了 popen3
的一个关键功能,那就是它会为您提供句柄,您可以随心所欲地使用它们:
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
# Use stdin, stdout, stderr as you wish.
end
当您的程序位于管道命令的下游时,其 STDIN 将提供前一个命令的输出。
当您使用 Open3.popen3
时,您可以完全控制分叉进程' STDIN
、STDOUT
、STDERR
。您需要手动为它提供所需的数据,并根据需要使用输出。
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
# consume outputs in STDOUT and STDERR, otherwise the ffmpeg process may be blocked if it produces a lot of outputs
Thread.new do
while stdout.read
end
end
Thread.new do
while stderr.read
end
end
while data = STDIN.read(64) # read output of the upstream command
stdin.write(data) # manually pipe it to the ffmpeg command
end
wait_thr.join
end
如果 "vpipe" 做的最后一件事是调用另一个命令,并且您想不加修改地传递 stdin、stdout 和 stderr,那么使用 Open3.popen3
就是一种浪费。请改用 exec
!这很容易。