0

I'm building an Alfred workflow with switchaudio-osx so I can change system audio input/output to specific source(s). Pretty new to shell script writing, and I conjured up this:

#!/bin/bash

#Command path
cmd="/usr/local/Cellar/switchaudio-osx/1.0.0/SwitchAudioSource"

#Available sources
source1="Built-in Output"
source2="USB Audio CODEC "
source3="Built-in Microphone"

#Switch output source to
systemOut="$cmd -t output -s $source1"
usbOut="$cmd -t output -s $source2"

#Switch system sound source to
systemSys="$cmd -t system -s $source1"
usbSys="$cmd -t system -s $source2"

#Switch input source to
usbIn="$cmd -t input -s $source2"
systemIn="$cmd -t input -s $source3"

case "{query}" in
    "systemOut") 
        $systemOut 
        $systemSys
    ;;
    "usbOut") 
        $usbOut
        $usbSys
    ;;
    "systemIn") 
        $systemIn
    ;;
    "usbIn") 
        $usbIn
    ;;
    *) 
        echo "No source detected"
    ;;
 esac

After running, the script returns an error message of:

Could not find an audio device named "Built-in" of type output.  Nothing was changed.
Could not find an audio device named "Built-in" of type system.  Nothing was changed.

So somehow $source1 was not read in full. From search I learned about IFS setting and using {} with string variables so I tried those. However error messages persist.

When I change $source1="Built-in Output" to "'Built-in Output'", error message returns:

Could not find an audio device named "'Built-in" of type output.  Nothing was changed.

When I change case statement command $systemOut to ${systemOut} or "$systemOut", both return with error message:

/usr/local/Cellar/switchaudio-osx/1.0.0/SwitchAudioSource -t output -s 'Built-in Output': No such file or directory
/bin/bash: line 25: /usr/local/Cellar/switchaudio-osx/1.0.0/SwitchAudioSource -t system -s 'Built-in Output': No such file or directory

What does this error message mean? It looks like String variables that contains commands in case statement were not executed the right way.

I also tried using $() and `` to contain the string variable that has my command, but getting the same type of error messages.

What's the syntax for embedding shell commands in case statement, or in bash script in general? Is it not a string whose value are the commands? Super newbie question. Sorry.

wileypoots
  • 31
  • 2
  • 1
    Building commands in variables is full of traps for the unwary, and should be avoided wherever possible. Variables are intended for storing *data* not executable code. Sometimes using an array works, but it's usually best to keep individual parameters in variables, and just *run* commands rather than trying to store them first. See [BashFAQ #50: I'm trying to put a command in a variable, but the complex cases always fail!](http://mywiki.wooledge.org/BashFAQ/050) (and many previous questions here.) – Gordon Davisson May 08 '20 at 22:14
  • This is technically a duplicate of ["How to store a command in a variable in a shell script?"](https://stackoverflow.com/questions/5615717/how-to-store-a-command-in-a-variable-in-a-shell-script), but the top answer there is involves `eval`, which you should *absolutely not use*! This unix&linux question is better: ["List of arguments in only one variable in bash"](https://unix.stackexchange.com/questions/432352/list-of-arguments-in-only-one-variable-in-bash). But really, just don't do it at all; execute commands, don't store them. – Gordon Davisson May 08 '20 at 22:34
  • Your case statement references `"{query}"` but it does not appear to be set anywhere? – ThatsWhatSheCoded May 09 '20 at 00:03
  • @GordonDavisson Thank you so much! The BashFAQ link is most helpful! Still digesting it but I found out that Bash automatically separate string into words with IFS trimming space, /n and /t, and it's complicated to set IFS. My commands were full of spaces so after I chained the commands something went wrong there. So I'll _run_ commands rather than store it in variables from now on to save the hassle... What an interesting way of handling variable in Bash! – wileypoots May 10 '20 at 17:26
  • 1
    @ThatsWhatSheCoded As I understand, `{query}` was preset in Alfred workflow as the input argument similar to $1. I've tested that part and it works. I think what went wrong was when I stored command strings in variables, IFS trimmed spaces and the command stored somehow wasn't read fully. – wileypoots May 10 '20 at 17:30

0 Answers0