Bash: Elegant ways to use multiple variables for shortening long strings?

I am aware of dockutil in homebrew but, I am trying to run a bash script that automatically adds dock icons to the dock on a fresh user account. dockutil has been uncooperative on fresh out of the box installs:

#!/bin/bash
#add items to dock
x="defaults write com.apple.dock persistent-apps -array-add "
y='"<dict><key>tile-data</key><dict><key>file-data</key<dict><key>_CFURLString</key><string>/Applications/'
z='</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>"'
f="$x"$y
eval $f\Google Chrome.app$z;
eval $f\Safari.app$z;
eval $f\Firefox.app$z;
eval $f\Messages.app$z;
eval $f\Slack.app$z;
eval $f\Microsoft Outlook.app$z;
eval $f\Microsoft Word.app$z;
eval $f\Microsoft Excel.app$z;
eval $f\App Store.app$z;
eval $f\System Preferences.app$z;
eval $f\zoom.us.app$z;
echo "DOCK ICON REORGANIZATION COMPLETE...";
killall Dock; sleep 1;
eval clear;
exit 0

The script is fine, but I am wondering if there is a more elegant solution to concatenating the x and y variables together into 'f', or if there is a way to combine all three, x,y, and z, into one variable that will allow me to input 'AnyApp.app' in the middle. Input appreciated, thanks!


Solution 1:

Storing parts of commands in variables and/or using eval is a good way to get weird parsing problems. I'd use a shell function instead:

addDockApp() {
    defaults write com.apple.dock persistent-apps -array-add \
        "<dict><key>tile-data</key><dict><key>file-data</key<dict><key>_CFURLString</key><string>/Applications/$1</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>"
}

addDockApp "Google Chrome.app"
addDockApp "Safari.app"
...etc

Alternately, you could write it as a loop, and iterate over the list of apps to add:

for app in "Google Chrome.app" "Safari.app" "Firefox.app" "Messages.app" \
    "Slack.app" "Microsoft Outlook.app" "Microsoft Word.app" "Microsoft Excel.app" \
    "App Store.app" "System Preferences.app" "zoom.us.app"
do
    defaults write com.apple.dock persistent-apps -array-add \
        "<dict><key>tile-data</key><dict><key>file-data</key<dict><key>_CFURLString</key><string>/Applications/$app</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>"
done