Search code examples
bashmacosquoting

Passing parentheses as script argument to macOs defaults command


I'm writing out a setup script for my dotFiles. Part of this script will get some basic contact info to display on the lock screen in case my laptop is found. At this stage, the message looks like this

"If found, please call 000-000-0000 or email [email protected]"

Here's the function I've written to do this:

function collectInfo() {
    echo "We'll set a lock screen message for anyone who finds your laptop."
    echo "Please enter a valid phone number: "
    read phonenumber
    echo "Please enter a valid email: "
    read contactemail
    msg="If found, please call "$phonenumber" or email "$contactemail
    sudo defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText $msg
    if [ $? -eq 0 ]; then
        echo "Data entered"
        defaults read /Library/Preferences/com.apple.loginwindow LoginwindowText
    else
        echo "There was an issue with your input.  Please try again"
        collectInfo
    fi
}

I hit a snag if I try to pass parentheses to the loginwindow setting, for instance (000) 000-0000. I can echo out $msg and it seems to be creating the string just fine. Is there some way to pass a string with parentheses as an argument, or will I have to use sed to knock them out?


Solution

  • There are two confounding factors here:

    • Failing to put quotes around $msg splits it into a number of separate arguments.
    • An argument that starts with ( and ends with ) is parsed by defaults as an array, so (000) was parsed as an array with one element.

    To ensure that your content is parsed as a string, you can begin and end it with literal quotes:

    defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "'$msg'"
    

    The outer double quotes (") are processed by the shell to ensure that the entire message is passed as just one argument; the inner single quotes (') are passed to defaults and guide how it parses the value.