How To Manage Plist Files With PlistBuddy

Would you like a very powerful tool to manage your plist files with bash scripts? Say hello to PlistBuddy.


PlistBuddy is a tool provided by Apple to perform operations on a plist file using bash commands. We can add, edit and delete any values in a plist. You can find it at: /usr/libexec/PlistBuddy.

In this article, we are going to see how PlistBuddy works and finally an example with a Xcode project.

Happy Reading!


PlistBuddy provides several commands to perform operations on a plist file:


It prints a list of commands available, value types supported and some examples of common usages.


We can use it to exit from the Interactive Shell. The changes won’t be saved in the plist file.


It saves the current changes in the plist file.


It discards the current changes not saved and reloads the last saved version of the plist file.

Clear [type]

It deletes the content of the file and creates a new root with the type specified in the parameter.

Print [entry]

It prints the value of entry. If we don’t specify the entry, it prints the entire file.

Set [entry] [value]

It updates entry setting the value specified in the parameter.

Add [entry] [type] [value]

It adds a new entry with the specified type and value.

Copy [entrySrc] [entryDst]

It copies the entry entrySrc in entryDst. We cannot override an existing entryDst value.

Delete [entry]

It deletes the entry from the plist file.

Merge [file] [entry]

It adds the content of a plist file to entry. If we omit the parameter entry, the content will be added at the root of the file.

Import [entry] [file]

It sets or creates the entry assigning the content of file. For example, we may copy the content of a txt file inside an entry of type string.

Note about Types

We’ve just seen that some commands have a parameter type. PlistBuddy supports the following types:

  • string
  • array
  • dict
  • bool
  • real
  • integer
  • date
  • data


  • Add to the dictionary mydict an integer element test with value 1:

    Add :mydict:test integer 1
  • Add at the index 0 of the array myarray a string with the value Hello:

    Add :myarray:0 string Hello
  • Delete the entire array:

    Delete :myarray
  • Import the content of a file and set it to the entry myfile:

    Import :myfile test.txt


When we run the command /usr/libexec/PlistBuddy, we can use the following options:

-c [command]

We can use it to run an inline command like:

/usr/libexec/PlistBuddy -c "Add :test integer 20" ~/Desktop/test.plist

The file will be automatically saved after the execution of the command.


We can use it to print the plist content in the form of a xml plist:

/usr/libexec/PlistBuddy -x -c "Print" ~/Desktop/test.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">


It prints the complete help info.

Interactive Shell

We can start learning PlistBuddy using its interactive shell to test the commands.

We can open the interactive shell like this:

/usr/libexec/PlistBuddy ~/Desktop/test.plist

With the command above, we are asking PlistBuddy to open the file test.plist in the Desktop. If the file doesn’t exist, PlistBuddy creates it printing the following output message:

File Doesn't Exist, Will Create: /Users/MyUser/Desktop/test.plist

In this example, we are using the path ~/Desktop/ only for the sake of explanation. We can use any paths where we have write permissions.

Once we open the interactive shell, we should have an output like this:


which is waiting a our input. At this point, we can write a command of PlistBuddy and press enter to execute it.

We can exit from the interactive shell with the command exit.

Usage with Xcode

Let’s consider a Xcode project with two targets:

Each target has its info plist file (AppFree.plist and AppFull.plist). These two files have a lot common information like the supported orientation, the launch screen name and so on. The maintenance of these plist files may be painful. If we have to add a new common value, we should add it in both files.

With PlistBuddy, we can improve this situation. We can move all the common values in a new plist file Base.plist:

Then, in Build Phases, we can add a new Run Script Phase and move it below Target Dependencies:

In this way, the script will be executed before compiling the application.

Inside the new script phase, we can merge Base.plist with the target info plist:


/usr/libexec/PlistBuddy -c "Merge $BASE_PLIST" "$INFO_PLIST"

The example above is for the target AppFull. For AppFree, we can use the same script and rename the plist file of INFO_PLIST.


The maintenance of a project with several targets is sometimes painful. Thanks to PlistBuddy, we can reduce the pain.

PlistBuddy is a very powerful tool. The only limit is our imagination.