如何在 MacOS 上设置自动脚本启动?

How to set up automatic script launch on MacOS?

提问人:NewbieCoder 提问时间:11/16/2023 更新时间:11/16/2023 访问量:54

问:

我不是程序员,所以我去用 ChatGPT 解决了我的问题。任务是这样的:创建一个脚本,每 2 分钟自动在 MacOS 上创建整个屏幕的屏幕截图,将它们保存到硬盘上的文件夹中,然后将它们上传到 Google Drive 上的文件夹中。使用 ChatGPT,创建了一个 bash 脚本,该脚本创建屏幕截图并调用将屏幕截图上传到 Google Drive 的 python 脚本。

问题是什么:脚本在手动运行时工作正常,但不会自动运行。虽然我先配置了 cron,然后启动了,但这两种方法都不起作用。

下面是一个 bash 脚本代码:

#!/bin/bash

# Переход в директорию скрипта
cd "/Users/evgenijserikov/Script Screenshots"

# Путь к скрытой папке для сохранения скриншотов
screenshot_dir="$HOME/.hidden_screenshots"

# Создать папку, если она не существует
mkdir -p "$screenshot_dir"

# Создать уникальное имя файла для скриншота с датой, временем, именем приложения и названием веб-страницы или диалога/группы в Telegram
timestamp=$(date +"%H:%M_%d-%m-%Y")
app_name=$(osascript -e 'tell application (path to frontmost application as text) to name as text')

# Получить название вкладки в Google Chrome или название диалога/группы в Telegram, если соответствующее приложение открыто
if [ "$app_name" = "Google Chrome" ]; then
    window_title=$(osascript -e 'tell application "Google Chrome" to get title of active tab of front window')
elif [ "$app_name" = "Telegram" ]; then
    telegram_dialog=$(osascript -e 'tell application "Telegram" to return name of the front chat of front window' 2>/dev/null)
fi

# Создать имя файла с учетом названия вкладки или диалога/группы (если есть)
if [ -n "$window_title" ]; then
    screenshot_file="$screenshot_dir/${timestamp}_${app_name}_${window_title}.png"
elif [ -n "$telegram_dialog" ]; then
    screenshot_file="$screenshot_dir/${timestamp}_${app_name}_${telegram_dialog}.png"
else
    screenshot_file="$screenshot_dir/${timestamp}_${app_name}.png"
fi

# Сделать скриншот всего экрана и сохранить в файл
screencapture -x "$screenshot_file"

# Загрузить скриншот на Google Drive
python3 upload_to_drive.py "$screenshot_file"

# Удалить скриншоты старше 48 часов из локальной папки
find "$screenshot_dir" -name "*.png" -mtime +2 -exec rm {} \;

下面是一个 python 脚本代码:

from googleapiclient.http import MediaFileUpload
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
import sys
from datetime import datetime, timedelta, timezone

# Путь к файлу скриншота передается как аргумент
screenshot_file_path = sys.argv[1]

# ID вашей папки на Google Drive
folder_id = '18W_MZKixax-xmgcwnSbFzm301C_4BXed'

# Загрузка сохраненных учетных данных
credentials = Credentials.from_authorized_user_file('/Users/evgenijserikov/Script Screenshots/token.json')

# Инициализация сервиса Google Drive
service = build('drive', 'v3', credentials=credentials)

# Вычисление времени 48 часов назад в формате ISO 8601 с учетом часового пояса UTC
time_48_hours_ago = datetime.now(timezone.utc) - timedelta(hours=48)
formatted_time = time_48_hours_ago.isoformat()

# Получение и удаление старых файлов из Google Drive
files = service.files().list(q=f"'{folder_id}' in parents and modifiedTime < '{formatted_time}'",
                             fields='files(id, name)').execute().get('files', [])

for file in files:
    service.files().delete(fileId=file['id']).execute()

# Создание метаданных файла
file_metadata = {
    'name': screenshot_file_path.split('/')[-1],
    'parents': [folder_id]
}

# Загрузка файла
media = MediaFileUpload(screenshot_file_path)
file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()

print(f"File ID: {file.get('id')}")

这是一行 crontab:

*/2 * * * * /Users/evgenijserikov/ScriptScreenshots/screenshot_script.sh

下面是一个 .plist 代码:

<?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.user.screenshot</string>
    <key>Program</key>
    <string>/Users/evgenijserikov/Script\ Screenshots/screenshot_script.sh</string>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StartInterval</key>
    <integer>120</integer>
</dict>
</plist>

你能帮我解决问题吗?

MacOS Sonoma 14.1 (MacBook Pro M1 PRO)。你能帮我解决问题吗?

python bash macOS cron 启动

评论

0赞 Barmar 11/16/2023
确保您已授予完全磁盘访问权限。cron
3赞 Ed Morton 11/16/2023
techxplore.com/news/2023-08-chatgpt-showdown-stack.html 上关于 ChatGPT 生成的代码的一些有趣的统计数据:“研究人员表示,512 个 ChatGPT 对问题的回答中有 52% 是不正确的。令人不安的是,在测试参与者喜欢的回答中,77%是错误的。因此,YMMV以此为起点。
0赞 NewbieCoder 11/16/2023
在隐私设置中,我打开了 cron 和 crontab 的完全磁盘访问权限
2赞 Gordon Davisson 11/16/2023
我认为这不能在 crontab 中工作,因为 cron 作业不会在与 GUI 会话相同的上下文中运行,并且无法访问它来截取屏幕截图。让它成为启动代理(而不是启动守护程序)应该可以解决这个问题,但随后你需要给它相关的隐私权限(请参阅这个 AskDifferent 问题)。
0赞 Mark Setchell 11/16/2023
也许您可以将其作为“登录项”运行,而不是使用它,否则它可能会访问您的 GUI 会话,正如@GordonDavisson指出的那样。你只需要把它包裹在一个永远的循环中,以及每 2 分钟发射一次。cronsleep 120

答: 暂无答案