0

I wrote some BASH code that executes a lot of external commands (causing side effects). So for developing and debugging I thought I wrap the executions in a shell function, so that the commands will either be executed or printed.

So that basic code is:

run()
{
    if [ "$print_commands" -ne 0 ]; then
        echo "$@"
    else
        "$@"
    fi
}

Unfortunately most of the external commands output something when successful (like "success"), so I had been using > /dev/null to redirect such output. However there are some status queries that do output the status, and that cannot be discarded.

So obviously I cannot add > /dev/null inside run; also I don't want to add a second function that redirects, duplicating most code.

I tried a solution like this:

silence='>/dev/null'
run some_command with params $silence

The idea was to set silence to the empty string when just printing the commands, which works, but when executing the commands I get:

error: unrecognized arguments: >/dev/null

Is there some half-way elegant solution without using eval?

2 Answers 2

1

Why not check another variable in the run function use it to determine redirection?

run()
{
    if [ "$print_commands" -ne 0 ]; then
        echo "$@"
    elif [ "$silence" -ne 0 ]; then
        "$@" > /dev/null
    else
        "$@"
    fi
}

Then:

silence=1 run some_command with params whose output is not needed
silence=0 run some_command with params whose output is needed

Or you could output the command to stderr instead of stdout:

run()
{
    if [ "$print_commands" -ne 0 ]; then
        echo "$@" >&2
    else
        "$@"
    fi
}
7
  • I wasn't aware that the syntax "var=val cmd ..." can be used for shell functions, too; I thought it's only available for external commands. Redirecting to stderr is not an option as there could be real error messages and I intend to paste the output to a terminal for execution (or into another script). See also the related question unix.stackexchange.com/q/726124/320598
    – U. Windl
    Nov 24, 2022 at 9:02
  • @U.Windl the more I look at this, the more it feels like you're reinventing set -n
    – muru
    Nov 24, 2022 at 9:03
  • You should be a bit more verbose on set -n (how to use it here?).
    – U. Windl
    Nov 24, 2022 at 9:20
  • @U.Windl to me it looks you have some script or something in which you prefix the commands with this run function. Instead of that, run the script with bash -n, or run set -n conditionally at the top of the script.
    – muru
    Nov 24, 2022 at 9:38
  • Sorry, but when using bash -n my_script, then nothing is being executed, so nothing is being output. I don't see the usefulness of set -n still...
    – U. Windl
    Nov 24, 2022 at 10:31
0

Based on https://unix.stackexchange.com/a/726123/320598 I decided to add an additional first parameter to run to control redirection to /dev/null:

run()
{
    declare silence="$1"; shift
    if [ "$print_commands" -ne 0 ]; then
        echo "$@"
    elif [ "$silence" -ne 0 ]; then
        "$@" > /dev/null
    else
        "$@"
    fi
}

run 0 non_redirected_command params
run 1 redirected_command params

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .