I am writing a bash script to automate our build process. I need to store a path in a settings plist file and retrieve it in a shell script, using plistbuddy.
The key below specifies the path where archives will be stored, a folder on the Desktop:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>archives_path</key>
<string>$HOME/Desktop/Archives/</string>
</dict>
</plist>
In my shell script I access the key:
SETTINGS_PATH="path/to/plist/file"
ARCHIVES=$(/usr/libexec/PlistBuddy -c "Print archives_path" "$SETTINGS_PATH")
#outputs "$HOME/Desktop/Archives/"
mkdir "$ARCHIVES/test/"
#outputs "mkdir: $HOME/Desktop/Archives: No such file or directory"
The ARCHIVES
var is not expanding to /Users/*username*/Desktop/Archives/
, as I'd expect.
I did a test by creating a var with the same string:
ARCHIVES="$HOME/Desktop/Archives/"
echo "$ARCHIVES"
#expands to "/Users/*username*/Desktop/Archives/"
mkdir "$ARCHIVES/test/"
#creates the 'test' directory
As this script will be run under an unknown user account how can I force the $HOME to expand properly.
Your $ARCHIVE
returned by the PlistBuddy
contains a literal $HOME
.
Simple demo:
str='$HOME/tmp/somefile'
echo "The HOME isn't expanded: [[$str]]"
it prints:
The HOME isn't expanded: [[$HOME/tmp/somefile]]
You can use eval
for the expansion like:
expanded_str1=$(eval "echo $str")
echo "The HOME is DANGEROUSLY expanded using eval: [[$expanded_str1]]"
which prints
The HOME is DANGEROUSLY expanded using eval: [[/Users/jm/tmp/somefile]]
But using eval
is dangerous! Evaling any string which isn't absolutely under your control is really dangerous.
So, you need manually replace the literal $HOME
with it's actual value. It can be done with many ways, for example:
expanded_str2="${str/\$HOME/$HOME}"
# or
expanded_str2=$(echo "$str" | sed "s!\$HOME!$HOME!")
# or
expanded_str2=$(echo "$str" | perl -plE 's/\$(\w+)/$ENV{$1}/g')
# or ... other ways...
Using
echo "$expanded_str2"
prints
/Users/jm/tmp/somefile