2

Where am I going wrong in this Bash?

declare current_state=`pacmd list-sources | sed -n 19p`
declare my_target='used by: 0'
echo $current_state = $my_target
if [ '$current_state' = '$my_target' ] ; then
    echo true
    pacmd set-default-sink "alsa_output.pci-0000_0c_00.4.analog-stereo"
    echo true
else
    echo false
    pacmd set-default-sink "alsa_output.pci-0000_0a_00.1.hdmi-stereo-extra2"
    echo false
fi

It is always outputting the else (false) option to terminal:

used by: 0 = used by: 0
false
false

I have tried if [[ '$current_state' = '$my_target' ]] , if [[ '$current_state' == '$my_target' ]], if [ '$current_state' == '$my_target' ], if [ '$current_state' == 'used by 0:' ], if [ '$current_state' = 'used by 0:' ], etc. It's always coming back as false.

For context, I was trying to use scripts from How to switch sound output with key shortcut but none of those work because my output indeces are 2, 3, and 30. Because that makes sense. Anyway, I found by running the pacmd list-sources while varying the manually selected outputs out of Sound Settings differences in a few lines. (Line 6 was what I initially tried, and it would report the status of one of index 2 (the first one, yes, the first) as state: IDLE, state: RUNNING, or state: SUSPENDED.) I managed to make the bash script work once to change from my headphones to my monitor, and then no more. So I tried changing where I look to this line 19 output which tells me if it's in use (I think) with either used by: 1 when active or used by: 0 when inactive to just toggle. But nope, no luck.

So then I get into the basic troubleshooting to make sure my if/else is evaluating correctly, and it's not. I don't know what I'm supposed to do here. Did I screw something up with declare?? I don't know.

8
  • 1
    "$current_state" = "$my_target" ... Use double quotes " around variables .... Single quotes prevent their expansion.
    – Raffa
    Nov 26, 2022 at 18:03
  • ... www.shellcheck.net Nov 26, 2022 at 18:08
  • 1
    pacmd list-sources usually results in lines with leading spaces/tabs ... That might result in the two strings you are comparing to be not equal ... Spaces count.
    – Raffa
    Nov 26, 2022 at 18:23
  • 1
    You can use =~ for partial match e.g. try [ " abc: 1" = "abc: 1" ] && echo "full match" || [[ " abc: 1" =~ "abc: 1" ]] && echo "partial match" ... notice the order of string and sub-string around =~ and the use of [[ ... ]]
    – Raffa
    Nov 26, 2022 at 18:38
  • 1
    You need the spaces around = i.e. "abc" = "abc" or otherwise it will evaluate true always e.g. "abc"="abcd" will evaluate true.
    – Raffa
    Nov 26, 2022 at 18:52

1 Answer 1

2

pacmd list-sources usually results in lines with leading spaces/tabs ... That might result in the two strings you are comparing to be not equal ... Spaces count.

You can use =~ for partial match e.g. try [ " abc: 1" = "abc: 1" ] && echo "full match" || [[ " abc: 1" =~ "abc: 1" ]] && echo "partial match" ... notice the order of string and sub-string around =~ and the use of [[ ... ]]

So modifying your code:

#!/bin/bash

current_state=$(pacmd list-sources | sed -n 19p)
my_target="used by: 0"
echo "$current_state" = "$my_target"
if [[ "$current_state" =~ "$my_target" ]] ; then
    echo true
    pacmd set-default-sink "alsa_output.pci-0000_0c_00.4.analog-stereo"
    echo true
else
    echo false
    pacmd set-default-sink "alsa_output.pci-0000_0a_00.1.hdmi-stereo-extra2"
    echo false
fi
1
  • Thanks for correcting my mistake. I'd have been banging my head on that for a few hours when I always got a true evaluation. And thanks for teaching that [[ ]] is necessary for =~; I tried to use the regex match operator and got an error with [ ]. This seems to work other than now after waking my computer up from sleep the output devices have been renamed and reindexed (2, 3, and now 47.)
    – Tim50001
    Nov 26, 2022 at 23:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.