How to use PlistBuddy using command substiution

1.3k views Asked by At

I am trying the following script

#!/bin/bash

OUTPUT="$(cat /Users/admin/Desktop/plist-script-output/keys-updated.txt | sed 's/"//g; s/^/-c "Print :/g; s/$/"/g' | tr '\n' ' ')"

FILE="/Users/admin/Desktop/plist-script-output/plist-data/data.plist"

PLISTBUDDY=$(/usr/libexec/PlistBuddy $OUTPUT $FILE 2>&1)
echo "$PLISTBUDDY"

The output of the above script is Unrecognized Command

The value of OUTPUT variable is

-c "Print :Ant-Conversion" -c "Print :Newitem" -c "Print :Area" -c "Print :Contact"

2>&1 this is added so as to print both the errors (does not exist keys) and proper output.

The keys-updated.txt contains the list of keys to be extracted from the plist files (not necessary all are present in the plist)

SOLUTION (NOT WORKING)

Tried the solution from @Nahuel. however the line

PLISTBUDDY=$(eval set -- $OUTPUT;/usr/libexec/PlistBuddy "$@" "$FILE")

provides only the list of keys which do not exist in the plist

This is the output I am receiving after using the solution from @Nahuel

Print: Entry, "Status", Does Not Exist

Print: Entry, "Notify", Does Not Exist

Print: Entry, "IsMvnMgrSupported", Does Not Exist

Print: Entry, "BuildsetFile", Does Not Exist

Print: Entry, "RollupClocReportToModule", Does Not Exist

Print: Entry, "Branches", Does Not Exist

Print: Entry, "Ant-Conversion", Does Not Exist

Print: Entry, "IndexTag", Does Not Exist

Print: Entry, "WO", Does Not Exist

Print: Entry, "Tags", Does Not Exist

Print: Entry, "Newitem", Does Not Exist

ON USING THE COMMAND DIRECTLY ON COMMAND LINE

admin:Desktop admin$ . /usr/libexec/PlistBuddy -c "Print :Area" -c "Print :Contact" -c "Print :Email" -c "Print :Language" -c "Print :Location" -c "Print :Name" -c "Print :Notes" -c "Print :Purpose" -c "Print :Track" -c "Print :Type" -c "Print :URL" -c "Print :Status" -c "Print :Notify" -c "Print :IsMvnMgrSupported" -c "Print :BuildsetFile" -c "Print :RollupClocReportToModule" -c "Print :Branches" -c "Print :Ant-Conversion" -c "Print :IndexTag" -c "Print :WO" -c "Print :Tags" -c "Print :Newitem" /Users/admin/Desktop/plist-script-output/plist-data/ActiveMQ.plist

The output turns out to be

Monitoring . cucducheuneun . cdcdcdcdc . Java . dvfvfvfvfvfvfv . ActiveMQ . cddcdcdcdc . An messaging (JMS) framework from the Apache Software Foundation.
Infrastructure . Framework . jdbcjdbcdjdcnnjn . Print: Entry, ":Status", Does Not Exist . Print: Entry, ":Notify", Does Not Exist . Print: Entry, ":IsMvnMgrSupported", Does Not Exist . Print: Entry, ":BuildsetFile", Does Not Exist . Print: Entry, ":RollupClocReportToModule", Does Not Exist . Print: Entry, ":Branches", Does Not Exist . Print: Entry, ":Ant-Conversion", Does Not Exist . Print: Entry, ":IndexTag", Does Not Exist . Print: Entry, ":WO", Does Not Exist . Print: Entry, ":Tags", Does Not Exist . Print: Entry, ":Newitem", Does Not Exist . Abort trap: 6

1

There are 1 answers

10
Nahuel Fouilleul On

After looking at sed, and tr commands. Seems /Users/admin/Desktop/plist-script-output/keys-updated.txt contains

Ant-Conversion
Newitem
Area
Contact

the whole can be done with bash builtins :

# local args arr pcmd (if inside a function)
# readarray -t arr </Users/admin/Desktop/plist-script-output/keys-updated.txt
# because readarray doesn't work on Mac
IFS=$'\n' read -d '' arr </Users/admin/Desktop/plist-script-output/keys-updated.txt

args=()
for pcmd in "${arr[@]}"; do
    args+=(-c "Print :$pcmd")
done

PLISTBUDDY=$(/usr/libexec/PlistBuddy "${args[@]}" "$FILE" 2>&1)

First answer:

OUTPUT='-c "Print :Ant-Conversion" -c "Print :Newitem" -c "Print :Area" -c "Print :Contact"'

The quotes are not syntactical because quote processing is done before variable expansion.

Not safe (injection), int this case using eval

PLISTBUDDY=$(eval /usr/libexec/PlistBuddy $OUTPUT $FILE 2>&1)

Can't think to something better for the moment

Slightly better

PLISTBUDDY=$(eval set -- $OUTPUT;/usr/libexec/PlistBuddy "$@" "$FILE" 2>&1)