Home > Back-end >  Adding a redirection to a bash command array
Adding a redirection to a bash command array

Time:01-08

I am storing a command to execute in a bash array, example:

declare -a cmd=("sudo" "dnf" "update")
"${cmd[@]}"

Last metadata expiration check: 0:24:45 ago on Fri 07 Jan 2022 03:35:34 PM EST.
Dependencies resolved.
Nothing to do.
Complete!

Now, say I want to redirect the output to make it less noisy. This works:

"${cmd[@]}" &>/dev/null

But I would prefer to store the redirect with the command array so it can be added/removed like any other command in the array:

declare -a cmd=("sudo" "dnf" "update" "&>/dev/null")
"${cmd[@]}"

Last metadata expiration check: 0:29:14 ago on Fri 07 Jan 2022 03:35:34 PM EST.
No match for argument: &>/dev/null

The output isn't being redirected, the final array element is just being passed like a normal argument. Is there any way to get this work (i.e. judicious use of eval) or a better strategy?

XY statement: I am trying to use conditionals to make my program output silent. I can do this with:

silent=true
cmd=("sudo" "dnf" "update")
if silent; then
  "${cmd[@]}" &>/dev/null
else # Be noisy
  "${cmd[@]}"
fi

This results in lots of duplicated code over the course of my program (every debug operation needs multiple command execution lines). Instead I would prefer appending the redirection to the array, such as:

silent=true
cmd=("sudo" "dnf" "update")
$silent && cmd =("&>/dev/null")
"${cmd[@]}"

This strategy works great for functions and arguments but not for redirections. While I can apply --quiet flags to some programs to achieve this, in some cases I would like to redirect stderr, redirect to file, etc.

CodePudding user response:

You have to use eval to process shell operations in the variable expansion.

declare -a cmd=("sudo" "dnf" "update" "&>/dev/null")
eval "${cmd[@]}"

CodePudding user response:

If you want to avoid duplicate "${cmd[@]}" code, you can use a subshell:

(
    [[ $silent == true ]] && exec &>/dev/null
    exec "${cmd[@]}"
)

I suggest the use of exec if cmd will always be an external command.

  •  Tags:  
  • Related