You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash if else编写dwmbar歌曲元数据函数问题排查

dwmbar调用playerctl展示媒体信息的代码错误排查

问题现象

在Bash环境下为dwmbar编写媒体信息模块,调用playerctl获取歌曲元数据,预期逻辑为:无媒体播放器运行、无内容播放(即playerctl status返回No players found)时模块不展示媒体内容;有播放内容时展示格式化的艺术家、歌曲名信息。但前两版实现无论是否有播放器运行,都会始终打印歌曲元数据,不符合预期。

前两版代码的错误点

原发帖版本错误

mpd() {
  PS=$(2>/dev/null playerctl status)

  echo "$(date): ${PS}" >> debug.log

  if [[ ${PS} == "No players available" ]];then          
      printf "^c$pink^ ^c$blue^$(playerctl metadata --format '{{ uc(artist) }}') "
      printf "^c$pink^$(playerctl metadata --format '{{ uc(title) }}')^c$blue^ "
    else    
      printf " "
      exit 0 
    fi
}   

存在三个核心问题:

  • 分支逻辑完全写反:将打印元数据的逻辑放在了“匹配到无播放器提示”的if分支中,有播放器运行的场景反而进入else分支输出空格,和预期逻辑完全颠倒
  • 匹配文本错误:playerctl无播放器时实际返回文本为No players found,代码中写的No players available和实际返回值不匹配,精确相等判断永远无法命中预期分支
  • 函数内误用exit:exit指令会直接终止整个Shell进程,在dwmbar的模块函数中调用会直接导致整个状态栏退出,函数内需要终止逻辑应该用return而非exit

第一次编辑后版本错误

mpd() {
  PS=$(2>/dev/null playerctl status)

  echo "$(date): ${PS}" >> debug.log
 
  if ! [[ "${PS}" =~ ".*No play.*" ]];then  
      MD=$(2>/dev/null playerctl metadata --format '{{uc(artist) }}|{{uc(title)}}')
      TITLE=$(echo ${MD} | cut -d'|' -f 1)
      ARTIST=$(echo ${MD} | cut -d '|' -f 2)

      printf "^c$pink^ ^c$blue^${TITLE}"
      printf "^c$pink^${ARTIST}^c$blue^ "
    else    
      printf " "
      exit 0 
    fi
}   

除了保留了原版本中函数内误用exit的问题外,存在两个核心错误:

  • Bash正则匹配写法错误:Bash中使用=~操作符做正则匹配时,右侧的正则表达式如果加双引号,所有正则元字符(比如.*)会被解析为普通字面字符,不再具备正则通配能力。代码中".*No play.*"被当成普通字符串匹配,永远无法和实际返回值匹配,导致! [[ 匹配 ]]的条件永远为真,无论是否有播放器都会执行打印元数据的逻辑,这就是该版本始终输出元数据的根本原因。
  • 字段切割逻辑写反:--format定义的输出顺序是artist在前、title在后,cut切割后把artist值赋值给了TITLE变量、title值赋值给了ARTIST变量,会导致展示时歌曲名和艺术家信息颠倒。

可正常运行的最终版本

该版本修复了上述所有问题:通过子串通配符匹配*"No players"*,不需要精确匹配完整提示文本,兼容不同版本playerctl的返回差异;分支逻辑符合预期,仅在有播放器时拉取元数据;去掉了会导致状态栏崩溃的exit调用。

mpd() {
PS=$(2>/dev/null playerctl status)
NP='No players'

  if [[ "$PS" == *"$NP"* ]]; then
    printf " "
  else
    printf "^c$pink^ ^c$blue^$(playerctl metadata --format '{{ uc(artist) }}') "
    printf "^c$pink^$(playerctl metadata --format '{{ uc(title) }}')^c$blue^ "
  fi
} 

内容的提问来源于stack exchange,提问作者2346254765

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:51:26