Automator Run Shell 脚本中的“Absurd Length”错误

问题描述

所以,我有这个摄像头系统,当它检测到运动时,它会自动将视频上传到 FTP 服务器。

那些文件,我想自动移动到另一个 FTP 服务器(我的家庭助理服务器),然后通过通知 ping 我的手机。

为了在两个 FTP 服务器之间下载和上传,我使用了一个名为 FavoriteFTP 的工具,用于 Mac OS X。它允许我设置可以通过命令行运行的配置文件

然后我通过 Automator 启动了 2 个“应用程序”以在最喜欢的 FTP 中启动不同的配置文件一个用于从远程 FTP 服务器下载所有文件,另一个用于将这些文件上传到另一个 FTP(我的家庭助理服务器)。

最后但并非最不重要的是,我制作了第三个 Automator 应用程序,使用 HandbrakeCLI 将文件从 AVI 转码为 MP4。

以下是 3 个 Automator 应用:

这是 ftpdownload 应用程序:

/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile "Download from FTP"

这是 ftptranscode 应用程序:

SRC="/Users/frederik/cctv/motion"
DEST="/Users/frederik/cctv/motion"
DEST_EXT=mp4
HANDBRAKE_CLI=HandBrakeCLI

for FILE in "$SRC"/.avi
do
    filename=$(basename "$FILE")
    extension=${filename##.}
    filename=${filename%.}
    /usr/local/bin/HandBrakeCLI -i "$FILE" -o "$DEST"/"$filename".$DEST_EXT
done
find /Users/frederik/cctv/motion -name '.avi' -exec rm -r     {} ;

这是 ftpsync 应用程序(上传到第二个 FTP):

/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile "Upload CH1 to HASS

然后我的 AppleScript 会无限循环地运行这 3 个应用程序

on idle
tell application "System Events"
    tell application "ftpdownload"
        run
        delay 10
    end tell
    tell application "ftptranscode"
        run
        delay 20
    end tell
    tell application "ftpsyncapp"
        run
    end tell
    tell application "ftpsyncappCH2"
        run
    end tell
    return 10
end tell
end idle

总结一下: ftpdownload 是从远程 FTP 服务器下载所有 AVI 文件的应用程序 ftptranscode 是将这些文件转换为 MP4 的应用程序 ftpsyncapp 是将这些文件上传到第二个 FTP 服务器的应用程序 和 ftpsyncappCH2 执行相同的操作,但仅适用于文件名中包含“CH2”一词的文件

问题来了 一两天后,我收到一个来自 Automator 脚本的错误(见下图)。但是我只得到一个窗口弹出窗口。所以我认为它只是 3 个自动化应用之一。

https://i.imgur.com/bmz7Xxv.png

这个循环次数好像有限制 (我只需要这个永远运行)

所以现在每天都要点“确定”,有点烦。

如何避免每天收到一次此错误消息,以便我的脚本可以永远循环运行?

解决方法

我将提供两个建议。

首先:不要使用自动程序,而是创建一个保持开放的脚本应用程序,该应用程序使用 AppleScript 的 do shell script 函数来完成这项工作。空闲处理程序看起来像这样:

on idle
    do shell script "/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Download from FTP'"
    
    do shell script "
        SRC='/Users/frederik/cctv/motion'
        DEST='/Users/frederik/cctv/motion'
        DEST_EXT=mp4
        HANDBRAKE_CLI=HandBrakeCLI

        for FILE in \"$SRC\"/.avi
        do
            filename=$(basename \"$FILE\")
            extension=${filename##.}
            filename=${filename%.}
            /usr/local/bin/HandBrakeCLI -i \"$FILE\" -o \"$DEST\"/\"$filename\".$DEST_EXT
        done
        find /Users/frederik/cctv/motion -name '.avi' -exec rm -r {} ;"
    
    do shell script "/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Upload CH1 to HASS'"
    
    do shell script "/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Upload CH2 to HASS'"
    
    -- check every 30 seconds
    return 30
end idle

请注意,do shell script 在大多数情况下会在前进到下一个 applescript 命令之前等待来自被调用脚本的响应,因此 delay 命令不是必需的。如果收藏夹 FTP 在分离的后台线程上运行其命令可能会导致问题,但这似乎不太可能。

此外,我使用了 30 秒的空闲时间,因为我不想过于频繁地重新调用 FavoriteFTP 应用程序。默认情况下,脚本应用程序有 1 秒的空闲间隔;返回 30 使该间隔为 30 秒,这应该足以让应用完成其最后一个周期。


其次,由于这实际上只是一组 shell 脚本,而您只是使用 AppleScript 作为定期运行它们的容器,因此您可以将整个内容编写为单个 shell 脚本:

/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Download from FTP'
SRC='/Users/frederik/cctv/motion'
DEST='/Users/frederik/cctv/motion'
DEST_EXT=mp4
HANDBRAKE_CLI=HandBrakeCLI

for FILE in \"$SRC\"/.avi
do
    filename=$(basename \"$FILE\")
    extension=${filename##.}
    filename=${filename%.}
    /usr/local/bin/HandBrakeCLI -i \"$FILE\" -o \"$DEST\"/\"$filename\".$DEST_EXT
done
find /Users/frederik/cctv/motion -name '.avi' -exec rm -r {} ;
/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Upload CH1 to HASS'
/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Upload CH2 to HASS'

将其保存到磁盘,并作为启动作业按计划运行。 Launchd 旨在做到这一点。您将编写一个看起来像这样的 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>user.ftp.transfer.mdvideos</string>
    <key>Program</key>
    <string>/path/to/shellscript</string>
    <key>StartInterval</key>
    <integer>30</integer>
</dict>
</plist>

将其保存在 ~/Library/LaunchAgents/user.ftp.transfer.mdvideos.plist,然后使用 unix 命令将其作为作业加载

launchctl load ~/Library/LaunchAgents/user.ftp.transfer.mdvideos.plist`

详情见man launchctlman launchd.plist

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...