windows - ruby - IO.popen not working lame stdin and stdout encoding -


i've been working pipes , io.popen in ruby , have come across problem can't figure out. trying write binary data flac process lame process file. code structure using below.

# file paths file = pathname.new('example.flac').realpath dest = pathname.new('example.mp3')  # execute process , return io object wav = io.popen("flac --decode --stdout \"#{file}\"", 'rb') lame = io.popen("lame -v0 --vbr-new - -", 'r+b')  # write output wav lame io object lame << wav.read  # close pipe writing (should indicate # process input stdin finished). lame.close_write  # open destiniation file , write lame stdout dest.open('wb'){|out|     out << lame.read }  # close pipes wav.close lame.close 

however, doesn't work. after flac has run, script hangs , lame remains idle (no processor usage @ all). no errors or exceptions occur.

i using cygwin on windows 7, cygwin ruby package (1.9.3p429 (2013-05-15) [i386-cygwin]).

i must doing wrong, appreciated. thanks!

extra #1

i wanting pipe in , out binary data lame process because trying create platform independent (ruby support limited of course) transcode audio files, , windows binary of lame supports windows' path names, , not cygwin's.

edit #1

i read in places (i did not save urls, i'll try looking them in browser history) io.popen has known issues blocking processes in windows , case.

i have played around other libraries including ruby's open3.popen3 , open4, following similar code structure 1 above, lame process still hangs , remains unresponsive.

edit #2

i found this article talked limitations of of windows's cmd.exe , how prevents use of streamed data files stdin.

i refactored code shown below test out, , turns out, lame freezes on stdin write. if removed (comment out) line, lame process executes (with 'unsupported audio format' warning). perhaps article said explain problem here.

# file paths file = pathname.new('example.flac').realpath dest = pathname.new('example.mp3')  # local variables read_wav = nil read_lame = nil  # flac process, exits succesfully io.popen("flac --decode --stdout \"#{file}\"", 'rb'){|wav|     until wav.eof         read_wav = wav.read     end }  # lame process, fails io.popen("lame -v0 --vbr-new --verbose - -", 'r+b'){|lame|     lame << read_wav # if comment out this, process exits, instead of hanging     lame.close_write     until lame.eof         read_lame << lame.read     end } 

edit #3

i found stackoverflow (in first answer) mentioned cygwin pipe implementation unreliable. perhaps not related windows (at least not directly) instead cygwin , emulation. have instead opted use following code, based upon icy's answer, which works!

flac = "flac --decode --stdout \"#{file}\"" lame = "lame -v0 --vbr-new --verbose - \"#{dest}\""  system(flac + ' | ' + lame) 

did try pipe | character?
tested on windows ruby installer

require 'open3'  command = 'dir /b | sort /r'  # windows example command open3.popen3(command) {|stdin, stdout, stderr, wait_thr|   pid = wait_thr.pid   puts stdout.read  #<a list of files in cwd in reverse order> } 

other ways: ruby pipes: how tie output of 2 subprocesses together?

edit: using io::pipe

require 'open3'  command1 = 'dir /b' command2 = 'sort /r'  reader,writer = io.pipe open3.popen3(command1) {|stdin, stdout, stderr, wait_thr|   writer.write stdout.read } writer.close  stdout, stderr, status = open3.capture3(command2, :stdin_data => reader.read) reader.close  puts "status: #{status}"   #pid , exit code puts "stderr: #{stderr}"   #use debug command2 errors puts stdout 

embedding 2 appears work, yet, blog referred said, 1 must wait first command finish (not real-time -- test ping command)

stdout2 = '' open3.popen3(command1) {|stdin, stdout, stderr, wait_thr|   stdout2, stderr2, status2 = open3.capture3(command2, :stdin_data => stdout.read) } puts stdout2 

Comments

Popular posts from this blog

matlab - Deleting rows with specific rules -

php - MySQLi multi_query results for later use -