当前位置: 首页 > 知识库问答 >
问题:

使用bash for循环结合嵌入式Applescript for bash脚本

壤驷瑾瑜
2023-03-14

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

该脚本的目的是在我的Mac电脑上打开一个新的终端选项卡,并在每个新终端中自动启动“screen-r$HOST”,直到主机2中的主机列表结束。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

我希望发生的是,对于代码,执行为每个主机打开屏幕为-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)

共有3个答案

拓拔安邦
2023-03-14

你可能会发现一个易于阅读和使用的here doc。此外,使用while read循环来迭代文件的行(参考:http://mywiki.wooledge.org/BashFAQ/001)

while read -r host; do
    echo "$host"

    osabody=$(cat << END_OSA
      repeat 2 times
        tell application "Terminal" to 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
END_OSA
)
    osascript -e "$osabody"
done < ~/bin/hosts2.txt

$(cat…命令替换的结束括号必须在单独的一行上,因为该行上必须只有heredoc的终止字。

井逸明
2023-03-14

你的代码有错误。

告诉应用程序“终端”激活应该是告诉应用程序“终端”激活

在bash中,变量扩展在单引号中也不起作用(单引号意味着一切都是按字面意思解释的),因此单引号中的行set host to$host将不起作用。

试试这个:

#!/bin/bash

for HOST in `cat ~/bin/hosts2.txt`
do echo $HOST
  osascript -e "repeat 2 times
  tell application \"Terminal\" to 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

编辑:我认为实际上还有另一个问题:当在Applescript中为字符串设置变量时,字符串需要用引号括起来。所以set host to$HOST会导致错误,因为它将$HOST("Pulsar"或"dev")的值解释为无法找到/执行的命令;它需要set host to\"$HOST\"来代替。我已经在上面更改了它。

余歌者
2023-03-14

你的脚本有几个问题:有些让它完全停止工作;有些让它做了错误的事情;还有一些一开始就不需要存在。还有几个其他的答案可以解决一些问题,但是他们都没有测试脚本,因为有很多问题他们没有解决。

...对于在hosts2中找到的每个主机。txt文件
。。。每个主机都列在自己的行中。

然后这句话:

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

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

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

正如@entraz已经指出的,使用单引号将阻止shell变量在osascript中扩展。

还有AppleScript本身。

我不清楚您为什么要包含重复循环。

该脚本的目的是在我的Mac电脑上打开一个新的终端选项卡,并在每个新终端中自动启动“screen-r$HOST”,直到主机2中的主机列表结束。txt文件。每个主机都列在自己的行中。它重复了2次,因为文本文档中只列出了2台主机

这是没有意义的,因为您实现了一个bash循环,以便将行读取到$HOST变量中。当然,您读取的是单词,而不是行,但是AppleScript重复是一个令人费解的问题。请将其存入。

然后你有这个:

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

这大约是您需要告诉终端激活的数量的无穷大倍。

这一行:

set host to $HOST

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

最后:

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

这是错误的<代码>执行shell脚本不是终端命令。这是一个属于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

 类似资料:
  • 我需要使我的输出像预期的输出一样。我试图添加符号,但输出不像预期的输出 这是我的代码:

  • 我有一个字符串列表,每个字符串有一个或多个单词。我需要从这个列表中列出一个独特的单词。我可以很容易地用两个嵌套的循环来完成,但我不明白为什么我不能用一个集合理解得到同样的结果。 嵌套循环: 嵌套循环的结果(正确): 集理解: 集合理解结果(不正确): 为什么我不能从设定的理解中得到同样的结果?

  • 我是Java的新手,我想使用循环来产生阶梯效果,但在每一行中添加越来越多的空格。这是我的密码- 最终的目标是让它打印以下内容: 但我的照片是这样的: 对不起,我知道这是初学者的东西,但我不知道还能去哪里。感谢任何帮助。多谢了。

  • 问题内容: 我有一段代码,但是我想提高性能。我的代码是: matrix2是4维np数组,而matrix1是2d数组。 我想通过使用np.tensordot(matrix1,matrix2)加快此代码的速度,但是后来我迷路了。 问题答案: 您可以只使用jit编译器 您的解决方案一点也不差。我唯一更改的是索引和变量循环范围。如果您有numpy数组和过多的循环,则可以使用编译器(Numba),这确实很简

  • 问题内容: 是否可以在不使用嵌入式结构的情况下继承类型的方法? 代码的第一个片段是将结构嵌入其中的工作代码,我可以在上调用该方法。我不喜欢的是,当我初始化时,我有(?)来初始化其中的结构。有没有解决的办法? 最终,我想做以下事情。where 是类型和初始化位置,也不需要初始化结构。以下代码不起作用,但可能清楚我的目标是什么。 我将添加更多使用的方法的结构,这就是我要问的原因。如果只拥有,我将拥有可

  • 本文向大家介绍嵌入式系统中经常要用到无限循环,你怎么用C编写死循环。相关面试题,主要包含被问及嵌入式系统中经常要用到无限循环,你怎么用C编写死循环。时的应答技巧和注意事项,需要的朋友参考一下 while(1){}或者for(;;)