【问题标题】:LaunchAgent cannot access macOS "protected" foldersLaunchAgent 无法访问 macOS“受保护”文件夹
【发布时间】:2021-07-12 10:54:47
【问题描述】:

我有一个执行此操作的 shell 脚本:

#!/bin/bash

ls -la "$HOME/Pictures/Photos Library.photoslibrary"

当我在 shell 中运行这个脚本时,它工作正常。如果我定义了一个执行此脚本的 LaunchAgent(在 $HOME/Library/LaunchAgents 下),我会收到以下错误消息:

ls: Photos Library.photoslibrary: Operation not permitted

我的真实脚本正在调用 HashBackup (hb),这会导致所有“受保护”文件夹(图片、地址簿等)出现相同类型的错误。但我能够用一个简单的ls 进行复制。

我应该怎么做才能解决这个问题?

这是在 macOS 10.14.6 上。

谢谢

【问题讨论】:

  • this Ask Different question 的任何答案都解决了问题吗?
  • 感谢@GordonDavisson,因为您链接到的问题显然是我要问的。

标签: macos permissions launch-agent


【解决方案1】:

感谢 Gordon 的评论,我能够按照这些步骤解决我的问题。实际对我有用的步骤是these

为了更完整的解决方案,这里是一个基于 CMake 的小型解决方案:

  1. main.cpp
#include <iostream>

int main()
{
  std::cout << "Wrapper app which is authorized for full disk access so that the shell script can run with the same permission" << std::endl;
  return 0;
}
  1. backup_argon.sh
#!/bin/bash

# this is just a test... it should invoke hb instead
ls -la "$HOME/Pictures/Photos Library.photoslibrary"
  1. Info.plist.in
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleExecutable</key>
    <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
    <key>CFBundleIconFile</key>
    <string>${MACOSX_BUNDLE_ICON_FILE}</string>
    <key>CFBundleIdentifier</key>
    <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
    <key>CSResourcesFileMapped</key>
    <true/>
    <key>NSHumanReadableCopyright</key>
    <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
    <key>LSUIElement</key>
    <true/>
    </dict>
</plist>
  1. CMakeLists.txt
cmake_minimum_required(VERSION 3.19)

set(VERSION 1.0.0)

project(HashBackupLaunchAgent VERSION "${VERSION}")

set(CMAKE_CXX_STANDARD 17)

set(MACOSX_BUNDLE_BUNDLE_NAME "HashBackupLaunchAgent")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.pongasoft.HashBackupLaunchAgent")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VERSION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${VERSION}")
set(MACOSX_BUNDLE_COPYRIGHT "2021 pongasoft")

add_executable(HashBackupLaunchAgent MACOSX_BUNDLE main.cpp backup_argon.sh)

set_target_properties(HashBackupLaunchAgent PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/Info.plist.in")

set_source_files_properties(backup_argon.sh PROPERTIES MACOSX_PACKAGE_LOCATION MacOS)

编译此项目将生成一个应用程序 (HashBackupLaunchAgent.app),我将其复制到 /Applications 下。

然后我将Full Disk Access 权限授予System Preferences/Security &amp; Privacy/ Privacy 下的此应用

然后我有一个具有以下定义的 LaunchAgent:

<?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>Label</key>
    <string>com.ypujante.hashbackup.argon.plist</string>

    <key>EnvironmentVariables</key>
      <dict>
        <key>PATH</key>
        <string>/bin:/usr/bin:/usr/local/bin</string>
      </dict>

    <key>ProgramArguments</key>
    <array>
        <string>/Applications/HashBackupLaunchAgent.app/Contents/MacOS/backup_argon.sh</string>
    </array>

    <key>StandardOutPath</key>
    <string>/Users/ypujante/Library/Logs/HashBackup/argon.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/ypujante/Library/Logs/HashBackup/argon.log</string>
    <key>StartCalendarInterval</key>
    <array>
      <dict>
          <key>Hour</key>
          <integer>7</integer>
          <key>Minute</key>
          <integer>30</integer>
      </dict>
    </array>
  </dict>
</plist>

请注意启动代理定义如何调用应用程序内部的脚本,而不是应用程序本身。而且它有效:脚本继承了应用程序的完整磁盘访问权限。

【讨论】:

    猜你喜欢
    • 2011-06-07
    • 1970-01-01
    • 2014-05-28
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多