我试图让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/