且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何检查Mac OS中是否安装了特定的应用程序/软件

更新时间:2021-06-27 22:14:40

以补充 @Bavarious'有用的答案:

以下是通用bash函数,它们通过返回应用程序的路径或其包ID(如果已安装)来测试是否安装了应用程序.如果将它们放在bash个人资料中,它们也可能会很方便进行交互使用.

Here are generic bash functions that expand on testing just whether an application is installed by returning either an application's path or its bundle ID, if installed. If you place them in your bash profile, they may come in handy for interactive use, too.

这两个功能仍然可以用作测试是否安装了应用程序;例如:
if ! whichapp 'someApp' &>/dev/null; then ... # not installed

Either function can still also be used as a test for whether an application is installed; e.g.:
if ! whichapp 'someApp' &>/dev/null; then ... # not installed

这两个函数都不区分大小写,并且在指定名称时,.app后缀是可选的. 但是请注意,本地化名称是 不能识别的.

Neither function is case-sensitive, and, when specifying a name, the .app suffix is optional. Note, however, that localized names are not recognized.

通过 捆绑包ID 名称查找应用程序的功能. 返回应用程序的路径(如果找到);否则,报告错误.

A function for locating applications by either bundle ID or name. Returns the application's path, if found; otherwise, reports an error.

示例:

  • whichapp finder # -> '/System/Library/CoreServices/Finder.app/'
  • whichapp com.apple.finder # -> '/System/Library/CoreServices/Finder.app/'
  • whichapp finder # -> '/System/Library/CoreServices/Finder.app/'
  • whichapp com.apple.finder # -> '/System/Library/CoreServices/Finder.app/'

给出应用程序的名称,返回其包ID.

Given an application's name, returns its bundle ID.

示例:

  • bundleid finder # -> 'com.apple.finder'

实施说明:在AppleScript代码中,很容易绕过Finder上下文并仅使用例如application [id] <appNameOrBundleId>path to application [id] <appNameOrBundleId>在全局上下文中,但是问题在于,总是启动目标应用程序,这是不希望的.

Implementation note: In the AppleScript code, it's tempting to bypass the Finder context and simply use e.g. application [id] <appNameOrBundleId> and path to application [id] <appNameOrBundleId> in the global context, but the problem is that that invariably launches the targeted application, which is undesired.

whichapp() {
  local appNameOrBundleId=$1 isAppName=0 bundleId
  # Determine whether an app *name* or *bundle ID* was specified.
  [[ $appNameOrBundleId =~ \.[aA][pP][pP]$ || $appNameOrBundleId =~ ^[^.]+$ ]] && isAppName=1
  if (( isAppName )); then # an application NAME was specified
    # Translate to a bundle ID first.
    bundleId=$(osascript -e "id of application \"$appNameOrBundleId\"" 2>/dev/null) ||
      { echo "$FUNCNAME: ERROR: Application with specified name not found: $appNameOrBundleId" 1>&2; return 1; }
  else # a BUNDLE ID was specified
    bundleId=$appNameOrBundleId
  fi
    # Let AppleScript determine the full bundle path.
  fullPath=$(osascript -e "tell application \"Finder\" to POSIX path of (get application file id \"$bundleId\" as alias)" 2>/dev/null ||
    { echo "$FUNCNAME: ERROR: Application with specified bundle ID not found: $bundleId" 1>&2; return 1; })
  printf '%s\n' "$fullPath"
  # Warn about /Volumes/... paths, because applications launched from mounted
  # devices aren't persistently installed.
  if [[ $fullPath == /Volumes/* ]]; then
    echo "NOTE: Application is not persistently installed, due to being located on a mounted volume." >&2 
  fi
}

注意:该功能还可以查找在给定会话中从已装载卷启动的应用程序.谢谢,

Note: The function also finds applications launched from a mounted volume in a given sessionThanks, Wonder Dog., but since such applications aren't persistently installed (not persistently registered with the macOS Launch Services), a warning is issued in that event.
If desired, you can easily modify the function to report an error instead.

bundleid() {
  osascript -e "id of application \"$1\"" 2>/dev/null || 
    { echo "$FUNCNAME: ERROR: Application with specified name not found: $1" 1>&2; return 1; }
}