1

I'm attempting to write a function for dwmbar in bash using playerctl to return metadata about a song.

If there is nothing playing, e.g. if playerctl status returns No players found. I want it to show nothing.

The example below however prints metadata at all times.

What have I done wrong?

[EDITED]

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    
      # Do you really need a space printed here?
      printf " "
      # Do you really need to exit from inside a function?
      exit 0 
    fi
}   

(Prior post)

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    
      # Do you really need a space printed here?
      printf " "
      # Do you really need to exit from inside a function?
      exit 0 
    fi
}   

Edit: this works

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
} 
2346254765
  • 31
  • 3
  • If `playerctl` outputs stuff on stderr, you can get rid of it by redirecting that to `/dev/null` like this: `$(playerctl status 2> /dev/null)`. – joanis Jun 18 '22 at 03:22
  • Are the asterisks in `*"No players"*` really in the script? – Ted Lyngmo Jun 18 '22 at 03:31
  • I'd recommend putting `set -x` at the beginning of the function to turn on execution tracing (and `set +x` at then end to turn it off), and see what bash thinks is happening as it runs. – Gordon Davisson Jun 18 '22 at 04:46
  • My guess is your comparison of [[ ${player_status} == "No Players Available" ]] is failing every time as the EXACT text "No Players Available" never appears. I suggest making it more imprecise, e.g. [[ ${player_status}== "No Pl"* ]]. – Jay M Jun 18 '22 at 06:40
  • @Ted Lyngomo: * In the compare makes it a wildcard compare. The [[ is a BASH compare so adds features over sh. The bash man page is horrid, but this page helps: https://linuxize.com/post/how-to-check-if-string-contains-substring-in-bash/ – Jay M Jun 18 '22 at 06:41
  • I've edited your code to help you find out what you should be comparing. – Jay M Jun 18 '22 at 06:43
  • Bash's regex parser treats quoted characters as literal rather than RE metacharacters, so with `[[ "${PS}" =~ ".*No play.*" ]]` it's looking for literal periods and asterisks in the string. You could use just `[[ "${PS}" =~ "No play" ]]` since RE patterns are not anchored by default (i.e. it searches for a matching *substring*, not necessarily a whole-string match). But also, please clarify the exact result you're getting from `playerctl status`. – Gordon Davisson Jun 18 '22 at 07:35

1 Answers1

2

This works:

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
} 
2346254765
  • 31
  • 3