Creating and writing into .plist with Terminal or bash script
Asked Answered
S

2

10

I need to create a .plist file during post install and the only option I can use is a bash script. I have to create a foo.plist into /Library/launchAgents with a bash script and I've used the following command:

cd /Library/launchAgents
touch foo.plist

now I need to write contents into this .plist file for example like this:

".plist contents" >> foo.plist

Is there a command that can do this in the terminal?

Slipstream answered 9/12, 2014 at 12:57 Comment(2)
Where are the plist contents that you want to write into the plist? I mean do you have a list of them in a file? With their corresponding valuse? Are they in a shell variable? Why do you have to use bash, why can't you use an editor?Rebba
yeah i have a working .plist file . I need to used bash because installer will run this bash script. so to automate the process as a post install step during installation.Slipstream
R
5

Your question doesn't specify very well what you have got, or why you need to do it in bash, but if you must do it that way, you can do it like this:

#!/bin/bash
VERSION=2.12
cat > foo.plist <<EOF
<?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>BuildAliasOf</key>
        <string>ProEditor</string>
        <key>BuildVersion</key>
        <value>$VERSION</value>
</dict>
</plist>
EOF

So, you save this in a file called Buildplist and then do this to make it executable

chmod +x Buildplist

and then you run it by typing this:

./Buildplist

You can make it write the plist file directly into /Library/launchAgents by changing the second line to something like this:

cat > /Library/launchAgents/yourApp/yourApp.plist <<EOF

You can make it accept parameters too. So if you want to pass the Author as the first parameter, you can do it like this:

#!/bin/bash
VERSION=2.12
AUTHOR="$1"
cat > foo.plist <<EOF
<?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>BuildAliasOf</key>
        <string>ProEditor</string>
        <key>BuildVersion</key>
        <value>$VERSION</value>
        <author>$AUTHOR</author>
</dict>
</plist>
EOF

and then run

./Buildplist "Freddy Frog"

to pass "Freddy Frog" as the author.

If you want to avoid overwriting any plist file that already exists, you can do it like this:

#!/bin/bash
PLISTFILE="/Library/launchAgents/yourApp/yourApp.plist"

# If plist already exists, do not overwrite, just exit quietly
[ -f "$PLISTFILE" ] && exit

cat > "$PLISTFILE" <<EOF
...
...
EOF

I put the name of the plist file in a variable to simplify maintenance, and avoid typing it twice.

Rebba answered 9/12, 2014 at 13:31 Comment(4)
"Why I have to do this?" because i want to execute a script during my application install . when installer "which is a DMG" and "PKG" installer completes installation i need to execute this bash script at the end to put this .plist file in /Library..Slipstream
is there any way i can check and skip if file already exists??Slipstream
Yes, of course. I have added a little extra at the end to show how to do that. Please have another look.Rebba
/usr/libexec/PlistBuddy is better.Rosaniline
R
23

PlistBuddy is what you want.

/usr/libexec/PlistBuddy Info.plist
File Doesn't Exist, Will Create: Info.plist

Then add an entry to the file like this,

/usr/libexec/PlistBuddy -c 'add CFBundleIdenfier string com.tencent.myapp' Info.plist

By the way, man plist, man plutil may be helpful for you.

Command Format:
    Help - Prints this information
    Exit - Exits the program, changes are not saved to the file
    Save - Saves the current changes to the file
    Revert - Reloads the last saved version of the file
    Clear [<Type>] - Clears out all existing entries, and creates root of Type
    Print [<Entry>] - Prints value of Entry.  Otherwise, prints file
    Set <Entry> <Value> - Sets the value at Entry to Value
    Add <Entry> <Type> [<Value>] - Adds Entry to the plist, with value Value
    Copy <EntrySrc> <EntryDst> - Copies the EntrySrc property to EntryDst
    Delete <Entry> - Deletes Entry from the plist
    Merge <file.plist> [<Entry>] - Adds the contents of file.plist to Entry
    Import <Entry> <file> - Creates or sets Entry the contents of file

Entry Format:
    Entries consist of property key names delimited by colons.  Array items
    are specified by a zero-based integer index.  Examples:
        :CFBundleShortVersionString
        :CFBundleDocumentTypes:2:CFBundleTypeExtensions

Types:
    string
    array
    dict
    bool
    real
    integer
    date
    data

Examples:
    Set :CFBundleIdentifier com.apple.plistbuddy
        Sets the CFBundleIdentifier property to com.apple.plistbuddy
    Add :CFBundleGetInfoString string "App version 1.0.1"
        Adds the CFBundleGetInfoString property to the plist
    Add :CFBundleDocumentTypes: dict
        Adds a new item of type dict to the CFBundleDocumentTypes array
    Add :CFBundleDocumentTypes:0 dict
        Adds the new item to the beginning of the array
    Delete :CFBundleDocumentTypes:0 dict
        Deletes the FIRST item in the array
    Delete :CFBundleDocumentTypes
        Deletes the ENTIRE CFBundleDocumentTypes array
Rosaniline answered 5/11, 2015 at 6:57 Comment(1)
I found this article incredibly helpful in addition to this answer: medium.com/@marksiu/what-is-plistbuddy-76cb4f0c262dBelisle
R
5

Your question doesn't specify very well what you have got, or why you need to do it in bash, but if you must do it that way, you can do it like this:

#!/bin/bash
VERSION=2.12
cat > foo.plist <<EOF
<?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>BuildAliasOf</key>
        <string>ProEditor</string>
        <key>BuildVersion</key>
        <value>$VERSION</value>
</dict>
</plist>
EOF

So, you save this in a file called Buildplist and then do this to make it executable

chmod +x Buildplist

and then you run it by typing this:

./Buildplist

You can make it write the plist file directly into /Library/launchAgents by changing the second line to something like this:

cat > /Library/launchAgents/yourApp/yourApp.plist <<EOF

You can make it accept parameters too. So if you want to pass the Author as the first parameter, you can do it like this:

#!/bin/bash
VERSION=2.12
AUTHOR="$1"
cat > foo.plist <<EOF
<?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>BuildAliasOf</key>
        <string>ProEditor</string>
        <key>BuildVersion</key>
        <value>$VERSION</value>
        <author>$AUTHOR</author>
</dict>
</plist>
EOF

and then run

./Buildplist "Freddy Frog"

to pass "Freddy Frog" as the author.

If you want to avoid overwriting any plist file that already exists, you can do it like this:

#!/bin/bash
PLISTFILE="/Library/launchAgents/yourApp/yourApp.plist"

# If plist already exists, do not overwrite, just exit quietly
[ -f "$PLISTFILE" ] && exit

cat > "$PLISTFILE" <<EOF
...
...
EOF

I put the name of the plist file in a variable to simplify maintenance, and avoid typing it twice.

Rebba answered 9/12, 2014 at 13:31 Comment(4)
"Why I have to do this?" because i want to execute a script during my application install . when installer "which is a DMG" and "PKG" installer completes installation i need to execute this bash script at the end to put this .plist file in /Library..Slipstream
is there any way i can check and skip if file already exists??Slipstream
Yes, of course. I have added a little extra at the end to show how to do that. Please have another look.Rebba
/usr/libexec/PlistBuddy is better.Rosaniline

© 2022 - 2024 — McMap. All rights reserved.