davetron5000 / optparse-plus

Start your command line scripts off right in Ruby
http://davetron5000.github.com/optparse-plus
Apache License 2.0
521 stars 54 forks source link

sh switches command's stderr into fullstop's stdout #108

Closed mbigras closed 7 years ago

mbigras commented 7 years ago

Is there a way to tell sh not to output the stderr of it's given command?

git clone is sending it's output to stderr; however, once sh gets ahold of it fullstop sends it to stdout.

The fix for me is to send the stderr of git clone to /dev/null but I'm not sure if this is ideal since I don't think it can be logged anymore once I do that, shown below:

         warn "deleting #{repo_dir} before cloning"
         FileUtils.rm_rf repo_dir
       end
-      unless sh("git clone #{repo_url}") == 0
+      unless sh("git clone #{repo_url} 2> /dev/null") == 0
         exit_now!("checkout dir already exists, use --force to overwrite")
       end
       Repo.new(repo_dir)

before sending git clone to /dev/null:

➜  fullstop master ✓ HOME=/tmp/fakehome bundle exec bin/fullstop --force /tmp/dotfiles.git 2> /dev/null
deleting dotfiles before cloning
stderr output of 'git clone /tmp/dotfiles.git': Cloning into 'dotfiles'...
done.

after sending git clone to dev/null:

➜  fullstop master ✓     HOME=/tmp/fakehome bundle exec bin/fullstop --force /tmp/dotfiles.git
deleting dotfiles before cloning

Is there a better way to go about grabbing a command's stderr with sh?

Edit:

Taking a look at Methadone::SH it looks like sh is logging the stderr output of git log here:

sh_logger.warn("stderr output of '#{command}': #{stderr}") unless stderr.strip.length == 0

And it also seems like warn outputs to stdout.

In the case of full stop wouldn't we not want this output:

    stderr output of 'git clone /tmp/dotfiles.git': Cloning into 'dotfiles'...
    done.

by going to stdout by default?

davetron5000 commented 7 years ago

If you want to prevent stdout and stderr logging ,you can set the sh logger. You can also access that logger and set its level higher (though note by default that logger is the app-wide logger).

You can then access the stderr using the block form:

sh "git clone" do |stdout,stderr|
  # ...
end

The thinking behind the default behavior is that when you use sh you generally aren't expecting stderr, so if you get some, it gets output to the log. If git is producing non-error messages to stderr, that is git deviating from UNIX standard and methadone can't possibly know about that to squelch the error output (you'd have the same issue using bash).

mbigras commented 7 years ago

git has a --quiet switch that will prevent it from sending logging info to stderr see the docs for more info and this pr for an example 😄