Skip to content

Feature request: corollary to sh that captures stdout #678

Open

Description

@jasonkarns

It seems a common occurrence for me to have custom tasks that need to invoke a shell command, and capture the output.

The "simple" solution is to use backticks or %x to capture the command's stderr/stdout. However, using that isn't safe or recommended. Further, it loses all the helpful verbose and noop capabities that rake's own sh provides.

What do others do in this situation? Would it be helpful to have a version of sh that captures stderr and stdout? (Or to upgrade sh such that the resulting response object has stderr and stdout?)

Any other alternatives I'm missing?

Activity

  1. changed the title [-]Feature request: corrollary to `sh` that captures stdout[/-] [+]Feature request: corollary to `sh` that captures stdout[/+] on Dec 16, 2025
  2. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  3. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  4. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  5. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  6. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  7. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  8. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  9. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  10. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  11. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  12. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  13. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  14. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  15. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  16. 213 remaining items

  17. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  18. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  19. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  20. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  21. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  22. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  23. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  24. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  25. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  26. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  27. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  28. Mariajose-prog commented on Mar 7, 2026

    @Mariajose-prog
  29. rubyFeedback commented on May 9, 2026

    @rubyFeedback

    The "simple" solution is to use backticks or %x to capture the command's stderr/stdout. However, using that isn't safe or recommended. Further, it loses all the helpful verbose and noop capabities that rake's own sh provides.

    What do others do in this situation?

    Personally I use `` a lot, but if I need more control I use IO.popen e. g.

    IO.popen(original_entry, :err => [:child, :out]).each
    

    Or a similar variant. I am not entirely certain how to do this in rake, but I use this
    for instance in one project where I grab output generated via "configure" or "make",
    then colourize it, before showing it to the end user. That way the colours help me
    (or the user) to identify compile problems and what not. I am not entirely certain
    how to do so in rake or how common that is though; usually rake is used mostly
    for smaller, simpler tasks, isn't it?

    By the way, I am also not certain I can agree with "isn't safe or recommended". For
    me it works very well and just fine. I think via IO.popen() you may not need shell/sh.
    But it depends on the use case perhaps.

    It seems a part of your question relates as to how ruby performs system-specific
    output. This is probably secondary to "sh" as sh would refer to the main shell in
    use, typically bash on a linux system. Does IO.popen() depend on sh? I think not.
    There is also another command ... IO.select or select or something like that, but
    personally I use IO.popen() if I need to do more complex things, `` for capturing
    less complex things, and for the most simple thing I just use system() as it is the
    simplest IMO. I guess the only change I would possibly like is for system() to
    be able to also return results or so that we can select how it operates, kind of
    a bit more like IO.popen. Or, to just unify this all, but this is a design choice so
    it should then better be suggested to ruby core perhaps.

  30. jasonkarns commented on May 21, 2026

    @jasonkarns
    ContributorAuthor

    By the way, I am also not certain I can agree with "isn't safe or recommended". For me it works very well and just fine. I think via IO.popen() you may not need shell/sh. But it depends on the use case perhaps.

    https://www.sourcery.ai/vulnerabilities/ruby-lang-security-dangerous-exec

    It is recommended to avoid. The surface area at risk is when the command comes from user input; so there are absolutely majority of cases where backticks, system or exec are fine. But the more it's used, the more likely an accidental unsafe use sneaks in because it has become habit.

    So the recommended guidance is to use the array form of system, because it's not vulnerable to interpolation attacks. If one ensures all their use of system uses array (via rubocop or something), then there's no need to quibble over which use-cases are "safe" vs "unsafe" due to their input sources.

    Which leads back to the original question.

    Presuming one wants to build consistent and robust rake tasks, (consistent handling of verbose mode, tracing/debugging, noop/drymode, etc) the only exec method that's available is rake's sh. Which provides all the rake niceties, and allows safe invocation using array form. However, that method does not provide simple capturing of stdout/stderr.

    If you want simply capturing of stdout/stderr, you switch to backticks. So then you lose rake's niceties, and the safety of system+array.

    What I'm looking for is for rake to provide a dsl method so that rake task authors can leverage all the consistent features of rake tasks; without losing either the simplicity of capturing stdout/stderr nor the safety provided by alternative exec forms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions