简体   繁体   中英

How to obtain an application's Bundle ID (or plist path) from only the PID?

Similar to "How to find Bundle Identifier from known PID?" and to "How to read plist information (bundle id) from a shell script , but different.. as those are both related to Xcode build variable expansion, etc.

My question is how, in a BASH shell, where they only known value is the process' PID, how can one obtain that process' PATH, or unique "Bundle ID".

I am sure there is a hideous regex to parse ps, but I'm hoping for something cleaner and more portable. The comments in those prior mentioned posts included

BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "${BUILD_ROOT}/${INFOPLIST_PATH}")

However, I do not think plistbuddy is installed on every Mac, and more importantly, my question is within a theoretical script, NOT within an Xcode build phase..

I've tried plutil , plistkit , and plistdump , and none of them seem to do the trick..

The reason I am trying to achieve this is to be able to execute defaults read / write functions without hardcoding the BundleID of the parent process. I know how to pass this info as an argument to a script.. but I want to be able to doubt check.. within the script.

No need for a hideous regex to parse the output of ps – the ps utility already does what you ask of it. Calling it with the (admittedly somewhat arcane looking) following options

ps [-ww] -o comm= -p <pid>

will return the path to the executable belonging to your PID (the -ww argument is only needed if you output to a terminal, as ps will truncate the returned path without it. It should not be necessary otherwise).

The problem with retrieving a bundle ID from there is that not all processes map to bundles with an Info.plist (which defines the bundle ID) – notably, *nix type executables are not bundles and thus have no bundle ID. Also, even in the case of app bundles, ps returns the core executable of an application, not the path to the bundle itself. As the path to the executable inside an application bundle is standardized, however (it resides in Path.app/Contents/MacOS ), you can retrieve it with a bit of directory traversal.

Assuming you have stored the output of the ps call above in the variable execfile , this

[[ ${execfile%/*} =~ ^.+/Contents/MacOS$ ]] && defaults read "${execfile%/*/*}"/Info CFBundleIdentifier

will retrieve bundle identifiers for likely paths by using defaults to retrieve the value of the CFBundleIdentifier key of the Info.plist file every application bundle contains at its root.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM