【发布时间】:2022-01-07 21:22:02
【问题描述】:
我将要执行的命令存储在 bash 数组中,例如:
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!
现在,假设我想重定向输出以减少噪音。这有效:
"${cmd[@]}" &>/dev/null
但我更喜欢使用命令数组存储重定向,以便可以像数组中的任何其他命令一样添加/删除它:
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
输出没有被重定向,最终的数组元素只是像普通参数一样被传递。有什么方法可以完成这项工作(即明智地使用 eval)或更好的策略?
XY 声明: 我正在尝试使用条件来使我的程序输出静音。我可以这样做:
silent=true
cmd=("sudo" "dnf" "update")
if silent; then
"${cmd[@]}" &>/dev/null
else # Be noisy
"${cmd[@]}"
fi
这会在我的程序过程中导致大量重复代码(每个调试操作都需要多个命令执行行)。相反,我更愿意将重定向附加到数组中,例如:
silent=true
cmd=("sudo" "dnf" "update")
$silent && cmd+=("&>/dev/null")
"${cmd[@]}"
此策略适用于函数和参数,但不适用于重定向。虽然我可以将 --quiet 标志应用于某些程序来实现这一点,但在某些情况下,我想重定向 stderr、重定向到文件等。
【问题讨论】:
-
如果你动态执行shell操作,你必须使用
eval。 -
您只能扩展参数。重定向发生在参数扩展之前。
-
为什么不用函数而不是用数组复制函数呢?
cmd(){ sudo dnf update;} -
顺便说一句,我真的反对
silent=true;当true和false是真正的底层命令时,将它们视为布尔值意味着在值未初始化或被注入的情况下,您可以进行任意命令替换。更安全地使用silent=0/silent=1,然后使用(( silent )) && ...以避免将数据视为代码。 -
@LéaGris 但是我将如何附加到函数?
标签: arrays bash shell io-redirection