delano / rye

Safe, parallel access to Unix shells from Ruby
http://delano.github.com/rye
MIT License
234 stars 32 forks source link

Rye:Err is raised when a ssh command returns 1 #31

Open hamann opened 11 years ago

hamann commented 11 years ago

Hi,

I'm playing with rye and discovered that rye behaves differently when executing commands local or via ssh

>> a = Rye.shell 'test','-d /bins'
=> [, , 1, ]
>> box = Rye::Box.new('localhost')
=> #<Rye::Box:localhost name=localhost cwd= umask= env="" safe=true opts={:port=>nil, :keys=>["/Users/hamann/.ssh/id_rsa"], :paranoid=>true} keys=["/Users/hamann/.ssh/id_rsa"]>
>> box.disable_safe_mode
false
>> box.execute 'test', '-d /bins'
Rye::Err:  (cmd: test -d /bins; status: 1)
    from /Users/hamann/workspace/sauspiel/barmaid/vendor/bundle/ruby/1.9.1/gems/rye-0.9.8/lib/rye/box.rb:858:in `rescue in run_command'
    from /Users/hamann/workspace/sauspiel/barmaid/vendor/bundle/ruby/1.9.1/gems/rye-0.9.8/lib/rye/box.rb:809:in `run_command'
    from /Users/hamann/workspace/sauspiel/barmaid/vendor/bundle/ruby/1.9.1/gems/rye-0.9.8/lib/rye/box.rb:473:in `method_missing'
    from (irb):9
    from /Users/hamann/.rbenv/versions/1.9.3-p392/bin/irb:12:in `<main>'

Why does rye raise an exception when I want to check if a directory exists?

delano commented 11 years ago

I chose to return an exception for non-zero exit codes to avoid any ambiguity around successes and failures. Ideally Rye.shell would be consistent with that, but the class usage is kind of a special case in the sense that it's really only used as a replacement for backticks or Kernel.cmd.

disable_safe_mode only affects the whitelist and escaping (e.g. globs, tildas, etc). Would a disable_exceptions method solve your problem?

rrepen commented 11 years ago

Hi,

I hit this problem with the "ps" command when I wanted to see if a process existed or not and ps return -1 when it does not found the process, which in my case, I was expecting.

To handle that I had to add an exception handler.

I would prefer to get the same as under the shell, with no output in my case and the exit status set to -1 and no exception.

Don't know if this is possible under Rye.

Best regards René PENNARUN

On 03/29/2013 06:13 PM, Delano Mandelbaum wrote:

I chose to return an exception for non-zero exit codes to avoid any ambiguity around successes and failures. Ideally Rye.shell would be consistent with that, but the class usage is kind of a special case in the sense that it's really only used as a replacement for backticks or |Kernel.cmd|.

|disable_safe_mode| only affects the whitelist and escaping (e.g. globs, tildas, etc). Would a |disable_exceptions| method solve your problem?

— Reply to this email directly or view it on GitHub https://github.com/delano/rye/issues/31#issuecomment-15650538.

hamann commented 11 years ago

Yes, disabling exception based on command return codes would resolve it. Thanks!

hamann commented 11 years ago

What's about raising an exception when stderr isn't empty?

hamann commented 11 years ago

mixlib-shellout e.g. has a method 'error!' which does exactly that, raise an exception when stderr isn't empty, but that has to be called explicitly, bound to the command called before. I think such an approach makes more sense => let the user decide when an exit code <> 0 is really critical or an exception

ianneub commented 10 years ago

:+1:

nco-webdev commented 10 years ago

Is there a fix for that issue now ? I'm trying to delete an unexisting file and I want to handle exception by my self but the stderr is always printed in my shell. I would just like to hide it and display a custom error message in place of. A clue ?

delano commented 10 years ago

@Hito01 You can pass the option :error => false to Rye::Box.new to avoid printing the STDERR.

nco-webdev commented 10 years ago

Well, I already tried this : Rye::Box.new(host, safe: false, user: 'root', :error => false)

But the error is still displayed in my terminal. $box.git "clone", "foo@git.bar.net:#{options[:g]} "

Here is the command that I try to execute. In fact the repository doesn't exist and so I get something like : Access denied. fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists.

Where am I wrong ?

delano commented 10 years ago

You can also try adding an exception hook for the Exception class which does nothing but return.

See: