rubin - Argument passerer til brug af popen3 (gyde)?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at skrive en perle, der interagerer med Android ADB-kommandoen. Jeg har problemer med at forsøge at forstå, hvordan argumenter overføres til delprocesser.


Jeg bruger POpen4-perlen, som kun er en wrapper omkring platformene specifikke open3/open4 moduler. På OSX kører jeg følgende, og jeg får tilbage det ønskede output:


>> require 'POpen4'
=> true
>> POpen4::popen4("/Library/android-sdk-mac\_x86/platform-tools/adb shell pm list packages -f") do |pout, perr, pin|
?> pout.each { |line| puts line.to\_s.strip }
>> end
package:/system/app/Fallback.apk=com.android.fallback
package:/system/app/SoundRecorder.apk=com.android.soundrecorder
..<snip>..
package:/system/app/VpnServices.apk=com.android.server.vpn
=> #<Process::Status: pid=13833,exited(0)>


Når jeg kører det samme på Win32 får jeg:


irb(main):001:0> require 'POpen4'
=> true
irb(main):002:0> POpen4::popen4("C:\Android\android-sdk-windows\platform-tools\adb.exe shell pm list packages -f")
Errno::ENOENT: No such file or directory - C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f
        from C:/Ruby192/lib/ruby/1.9.1/open3.rb:202:in `spawn'
        from C:/Ruby192/lib/ruby/1.9.1/open3.rb:202:in `popen\_run'
        from C:/Ruby192/lib/ruby/1.9.1/open3.rb:90:in `popen3'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/win32-open3-19-0.0.1/lib/win32/open3.rb:5:in `popen4'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/POpen4-0.1.4/lib/popen4.rb:48:in `popen4'
        from (irb):2
        from C:/Ruby192/bin/irb:12:in `<main>'


Hvis jeg overvåger, hvad Ruby gør ved hjælp af procexp, kan jeg se, at det behandler hele argumentet til popen4 som kommandoen til at køre:


ruby.exe    5800    QueryDirectory  C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.exe NO SUCH FILE
ruby.exe    5800    QueryOpen   C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.exe FAST IO DISALLOWED  
ruby.exe    5800    CreateFile  C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.exe NAME NOT FOUND
ruby.exe    5800    QueryDirectory  C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.com NO SUCH FILE
ruby.exe    5800    QueryOpen   C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.com FAST IO DISALLOWED  
ruby.exe    5800    CreateFile  C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.com NAME NOT FOUND
ruby.exe    5800    QueryDirectory  C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.cmd NO SUCH FILE
ruby.exe    5800    QueryOpen   C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.cmd FAST IO DISALLOWED  
ruby.exe    5800    CreateFile  C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.cmd NAME NOT FOUND
ruby.exe    5800    QueryDirectory  C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.bat NO SUCH FILE
ruby.exe    5800    QueryOpen   C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.bat FAST IO DISALLOWED  
ruby.exe    5800    CreateFile  C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f.bat NAME NOT FOUND
ruby.exe    5800    CreateFile  C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f NAME NOT FOUND
ruby.exe    5800    CreateFile  C:Androidandroid-sdk-windowsplatform-toolsadb.exe shell pm list packages -f NAME NOT FOUND


Selvom popen3 docs siger, at dette skal behandles som kommandolinje og argumenter:


The parameters +cmd…+ is passed to Process.spawn. So a commandline string and list of argument strings can be accepted as follows.

  Open3.popen3("echo a") {|i, o, e, t| ... }
  Open3.popen3("echo", "a") {|i, o, e, t| ... }
  Open3.popen3(["echo", "argv0"], "a") {|i, o, e, t| ... }


Hvad mangler jeg her?

Bedste reference