bash - 将 bash for 循环与 bash 脚本的嵌入式 applescript 结合使用

标签 bash applescript

我试图让applescript与bash for循环交互,这是我代码的一部分,以避免必须手动列出每个主机并为hosts2.txt中找到的每个主机执行单独的tell/endtell block 文件。

该脚本的目的是在我的 Mac 上打开一个新的终端选项卡,并在每个新终端中自动启动“screen -r $HOST”,直到 Hosts2.txt 文档中的主机列表末尾。每个主机都在其自己的行中列出。

我尝试了一个全包式的 for 循环,没有如下所示的 applescript“重复 2 次”“结束重复”代码。它重复 2 次,因为出于测试目的,文本文档中仅列出了 2 个主机。每次我都有错误输出。

#!/bin/bash

for HOST in `cat ~/bin/hosts2.txt`
do echo $HOST
    osascript -e 'repeat 2 times
    tell application "Terminal" activate
tell application "System Events" to keystroke "t" using [command down]
tell application "Terminal" to activate
set host to $HOST
tell application "Terminal"
do shell script "screen -r " & host in front window
end tell
end repeat'
done

我期望发生的事情是执行代码,使用 screen -r 为每个主机打开新的终端选项卡。错误输出位于此行下方。

dev
44:52: syntax error: Expected end of line but found command name. (-2741)
pulsar
44:52: syntax error: Expected end of line but found command name. (-2741)

最佳答案

您的脚本存在一些问题:有些问题完全阻止了它的工作;有些人让它做错事;还有一些本来就不需要存在的东西。还有几个其他答案解决了某些问题,但他们似乎都没有测试脚本,因为他们没有解决很多问题。

...for each host found in the hosts2.txt file...
...Each host is listed on its own line.

然后这一行:

for HOST in `cat ~/bin/hosts2.txt`

不是你想要的。这将从单个单词而不是文件中的行创建一个数组。您想使用read命令,逐行读取文件。您可以按以下方式构建循环:

while read -r HOST; do
    .
    .
    .
done < ~/bin/hosts2.txt

@entraz已经指出,使用单引号将阻止 shell 变量在 osascript 内扩展.

然后是 AppleScript 本身。

我不清楚你为什么包含 repeat循环。

The purpose of the script is to open a new terminal tab on my Mac and automatically launch "screen -r $HOST" in each new terminal until the end of the list of hosts in the hosts2.txt document. Each host is listed on its own line. It is repeating 2 times because there are only 2 hosts listed in the text document

考虑到您实现了 bash 循环以便将行读入 $HOST,这没有任何意义。多变的。诚然,您阅读的是单词,而不是行,而是 AppleScript repeat是一个令人头疼的问题。将其装箱。

然后你就得到了这个:

tell application "Terminal" activate
tell application "System Events" to keystroke "t" using [command down]
tell application "Terminal" to activate

这大约是您需要的数字的无限倍 tell 终端activate

这一行:

set host to $HOST

会因两个原因抛出错误:首先,host在 AppleScript 的标准添加中被视为属性的现有名称,因此您无法将其设置为新值;其次,$HOST周围没有引号。 ,所以它不会被识别为字符串。但是,这仅供您学习,因为我们实际上将完全摆脱该行。

最后:

tell application "Terminal"
    do shell script "screen -r " & host in front window
end tell

是错误的。 do shell script不是终端命令。这是属于 AppleScript 标准添加的命令。因此,如果其余代码有效,并且到达此命令,终端将不会执行任何操作。相反,shell 脚本将在没有实际 shell 的情况下在后台运行,因此这对您来说没有多大好处。

您要执行的命令是 do script .

遗憾的是,至少在 High Sierra 中,在终端中创建新选项卡和窗口的 AppleScript 命令似乎不再起作用,所以我明白为什么您求助于系统事件以您所拥有的方式创建选项卡。值得庆幸的是,这不是必需的,您的倍数 activate 也不是必需的。命令:do script默认情况下,将自动运行终端并在新选项卡中执行脚本。

因此,您需要的唯一 AppleScript 命令是:

tell application "Terminal" to do script "screen -r $HOST"

最终脚本

将所有这些放在一起,这是最终的混合脚本:

while read -r HOST; do
    echo "$HOST"
    osascript -e "tell application \"Terminal\" to do script \"screen -r $HOST\""
done < ~/bin/hosts2.txt

或者

如果您想从 bash 中获取循环并将其放入 AppleScript 中,您可以这样做,为此我将使用heredoc ( << ) 来简化引号的使用并提高可读性:

osascript <<OSA
    property home : system attribute "HOME"
    property file : POSIX file (home & "/bin/hosts2.txt")

    set hosts to read my file using delimiter {return, linefeed}

    repeat with host in hosts
        tell application "Terminal" to do script ("screen -r " & host)
    end repeat
OSA

关于bash - 将 bash for 循环与 bash 脚本的嵌入式 applescript 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54041475/

相关文章:

ruby-on-rails - Rails 应用程序不读取 .bashrc 中的环境变量

cocoa - OSX 将鼠标左键单击分配给键盘按键

python - "No user interaction allowed"在 python 中运行 AppleScript 时

firefox - 如何指示 Applescript 打开带有链接的新 Firefox 窗口?

macos - 有什么方法可以在 AppleScript 中暂时暂停脚本吗?

automation - 如何在预定时间运行applescript

macos - CocoaDialog 文本框显示第一行

bash - git add - 当唯一的错误是存在被忽略的文件时,我可以强制退出代码 0 吗?

linux - 每天在 bash 中提取文件行

java - 无法使用用于执行 Java 程序的 Linux 脚本