Score:2

Bash Equivalency Struggles

ai flag

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.

Raffa avatar
jp flag
`"$current_state" = "$my_target"` ... Use double quotes `"` around variables .... Single quotes prevent their expansion.
hr flag
... [www.shellcheck.net](https://www.shellcheck.net/)
Tim50001 avatar
ai flag
@Raffa no luck in doing that. Just made that single change from the code originally posted, and it's still evaluating as false.
Tim50001 avatar
ai flag
@steeldriver using that site I can get code that says there are **No issues detected!** with this code. And it still doesn't work. ``` #!/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 ```
Raffa avatar
jp flag
`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.
Tim50001 avatar
ai flag
@Raffa that helped. The problem is I used ` = ` instead of `=`. By removing the surrounding spaces on the equivalence operator, it worked. At least to evaluate as true. I still have work to do on my troubleshooting, as it isn't doing a toggle. I'll have to explore a persistent variable as a toggle I think as my answer, rather than reading an output.
Raffa avatar
jp flag
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 avatar
jp flag
You need the spaces around = i.e. `"abc" = "abc"` or otherwise it will evaluate true always e.g. `"abc"="abcd"` will evaluate true.
Score:2
jp flag

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
Tim50001 avatar
ai flag
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.)
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.