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

bat*_*adi 8 macos installation

我想使用Perl/Shell脚本检查Mac OS中是否安装了特定的应用程序.我正在使用PackageMaker编写包,在安装应用程序之前,我需要在几个应用程序中检查用户计算机.所以我打算写一个脚本来为我检查这个.如果我能以更好的方式执行此操作,请提供建议.

mkl*_*nt0 11

补充@Bavarious'有用的答案:

以下是通用bash函数,通过返回应用程序的路径或其捆绑ID(如果已安装)来扩展测试是否安装了应用程序.如果将它们放在bash配置文件中,它们也可以派上用场进行交互式使用.

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

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

whichapp

一种用于通过定位应用功能要么包ID 名称.返回应用程序的路径(如果找到); 否则,报告错误.

例子:

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

bundleid

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

例:

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

实现说明:在AppleScript代码中,很容易绕过Finder上下文并简单地使用eg application [id] <appNameOrBundleId>path to application [id] <appNameOrBundleId>全局上下文,但问题是它总是会启动目标应用程序,这是不受欢迎的.

来源:whichapp

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
}
Run Code Online (Sandbox Code Playgroud)

注意:该函数还可以查找在给定会话中从已安装卷启动的应用程序,谢谢,Wonder Dog.,但由于此类应用程序未持久安装(未持久注册到macOS Launch Services),因此会在该事件中发出警告.
如果需要,您可以轻松修改函数以报告错误.

来源:bundleid

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


小智 7

以下bash脚本使用AppleScript根据Michael Pilat的解决方案检查是否安装了应用程序:

#!/bin/bash

APPLESCRIPT=`cat <<EOF
on run argv
  try
    tell application "Finder"
      set appname to name of application file id "$1"
      return 1
    end tell
  on error err_msg number err_num
    return 0
  end try
end run
EOF`

retcode=`osascript -e "$APPLESCRIPT"`
exit $retcode
Run Code Online (Sandbox Code Playgroud)

该脚本需要一个应用程序标识符(例如com.apple.preview).执行脚本后,retcode如果安装了应用程序,则包含1;如果未安装应用程序,则包含0.该脚本也会返回retcode.

例如:

$ ./appinst.sh com.apple.preview
$ echo $?
1
$
Run Code Online (Sandbox Code Playgroud)

要么

$ ./appinst.sh nonono
$ echo $?
0
$
Run Code Online (Sandbox Code Playgroud)

  • 酷的东西.这是一个更简洁的变体:一个bash函数,它接受一个包ID,如果找到则返回应用程序的路径,否则返回一个空字符串:`getAppPathByBundleId(){osascript -e'try'-e'告诉应用程序"Finder"返回POSIX路径(应用程序文件ID的路径"'"$ 1"'")作为文本'-e'结束尝试'; }`.另请参阅我的应用程序名称测试和查找应用程序包ID的答案.(请注意,正如我刚刚学到的那样,通过艰难的方式来绕过Finder上下文并简单地使用例如`application id"com.apple.reminders"`,这很有吸引力,但是_Implicitly启动指定的应用程序.) (2认同)

And*_*Vit 6

您可以system_profiler为此使用该命令。尝试这样的事情:

system_profiler SPApplicationsDataType | grep AppName
Run Code Online (Sandbox Code Playgroud)

  • 知道这一点很好,但在只对特定应用程序感兴趣的脚本中使用可能太慢了。 (2认同)