I have a Bash function that calls `notify-send` with a fixed set of options, plus an optional `--icon="$file"` argument when `$target` is not `pixel`. Right now I build an array first so I can invoke `notify-send` only once:
```bash
notify() {
local -a args
if [[ "$target" != pixel ]]; then
args=(--icon="$file" "$@")
else
args=("$@")
fi
notify-send --hint=string:x-dunst-stack-tag:shot
--hint=string:synchronous:shot --app-name=screenshot "${args[@]}"
}
```
The `args=("$@")` branch feels a little unnecessary, but duplicating the command just to conditionally add one argument also seems repetitive. Is there a cleaner and still safe way to handle this?
3 Answers
The array assignment is perfectly fine, but you can avoid the temporary array by conditionally prepending to the function’s positional parameters:
```bash
notify() {
if [[ $target != pixel ]]; then
set -- --icon="$file" "$@"
fi
notify-send --hint=string:x-dunst-stack-tag:shot
--hint=string:synchronous:shot --app-name=screenshot "$@"
}
```
Because this happens inside the function, `set --` only changes that function’s positional parameters. Quoting the arguments preserves spaces and prevents them from being interpreted as shell syntax.
A parameter expansion can be used for an optional argument, but it is easy to get quoting wrong. An unquoted expansion may split words or perform pathname expansion, while a quoted expansion can leave an empty argument behind. For command arguments, an array is generally clearer and safer than trying to construct a shell fragment with expansion or `eval`.
Exactly—`eval` should not be needed here. Building an array and expanding it with `"${args[@]}"` is the robust approach.
You can also append conditionally to an array, then append the original arguments:
```bash
notify() {
local -a args
[[ $target != pixel ]] && args+=(--icon="$file")
args+=("$@")
notify-send --hint=string:x-dunst-stack-tag:shot
--hint=string:synchronous:shot --app-name=screenshot "${args[@]}"
}
```
This keeps everything as separate array elements, so filenames or other arguments containing spaces remain safe. It also avoids duplicating the `notify-send` invocation.

This is shorter, although I prefer keeping the explicit array when I want the argument construction and error handling to be especially obvious. The practical difference here is negligible.