bash 命令替换中的逻辑

bash logic inside command substitution

我在登录时显示了一个小横幅

fignow() { figlet -w $(tput cols) $(date +"%b %d, Week %V"); figlet -w $(tput cols) -f univers $(date +"%H:%M"); }

如果安装额外的字体以获得 univers,这会很好用,但这不是默认安装的一部分,所以我可以执行以下操作:

fignow() { figlet -w $(tput cols) $(date +"%b %d, Week %V"); if [ -f /usr/share/figlet/univers.flf ]; then figlet -w $(tput cols) -f univers $(date +"%H:%M"); else figlet -w $(tput cols) $(date +"%H:%M"); fi; }

这也能正常工作,但我很好奇是否可以删除 if/else/fi 并且可以在命令本身内部完成逻辑,即类似于:

fignow() { figlet -w $(tput cols) $(date +"%b %d, Week %V"); figlet -w $(tput cols) -f $(use-univers-or-failback-to-standard.flf-if-univers.flf-is-not-available) $(date +"%H:%M"); }

这样的事情可能吗?

我建议:

fignow() {
  local opts
  figlet -w $(tput cols) $(date +"%b %d, Week %V")
  [ -f /usr/share/figlet/univers.flf ] && opts="-f univers"
  figlet -w $(tput cols) $opts $(date +"%H:%M")
}

仅当文件存在时变量 $opts 包含必要的选项。

我建议使用 figlist 以避免对主题路径进行硬编码:

figlet -w "$(tput cols)" -f "$((figlist | /bin/grep -hw universe) || echo "standard")" "foo"

检查文件或解析 figlist 或 showfigfonts 的输出本质上是脆弱的。只需调用 figlet 即可查看该选项是否可用。类似于:

fignow() {
        local font=${1-universe}
        figlet -f "$font" a > /dev/null 2>&1 || font=
        figlet -w $(tput cols) $(date +"%b %d, Week %V")
        figlet -w $(tput cols) ${font:+-f "$font"} $(date +"%H:%M")
}

请注意,这是您 不能 在变量周围使用双引号的情况之一,因为您希望 ${font:+-f "$font"}$font 为空。如果你使用 "${font:+-f "$font"}",语义会改变,一个空字符串被传递给 figlet。