Использование bash для циклов в сочетании со встроенным яблочным скриптом для скриптов bash - PullRequest
0 голосов
/ 04 января 2019

Я пытаюсь заставить яблочный скрипт взаимодействовать с циклом bash for, который является частью моего кода, чтобы избежать необходимости перечислять каждый хост вручную и выполнять отдельные блоки Tell / End Tell для каждого хоста, найденного в hosts2.txt. файл.

Цель скрипта - открыть новую вкладку терминала на моем Mac и автоматически запускать «screen -r $ HOST» в каждом новом терминале до конца списка хостов в документе hosts2.txt. Каждый хост указан в отдельной строке.

Я пробовал цикл «все включено» без кода «повторить 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)

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Вы можете найти готовый для чтения документ, с которым легко работать. Кроме того, используйте цикл while-read для перебора строк файла (ref: 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 должно быть единственными символами в этой строке.

0 голосов
/ 04 января 2019

Есть несколько проблем с вашим скриптом: некоторые мешают ему работать полностью; некоторые заставляют его поступать неправильно; и некоторые, которые не должны были быть там во-первых. Есть несколько других ответов, которые касаются некоторых моментов, но ни один из них, по-видимому, не тестировал сценарий, потому что есть много, к которым они не обращаются.

... для каждого хоста, найденного в файле hosts2.txt ...
... Каждый хост указан в отдельной строке.

Тогда эта строка:

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

это не то, что вы хотите. Это создаст массив из отдельных слов, а не строк в файле. Вы хотите использовать команду read, которая читает файл построчно. Вы можете структурировать цикл следующим образом:

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

Как уже указывал @ entraz , использование вами одинарных кавычек остановит расширение переменных оболочки внутри вашего osascript.

Тогда есть сам AppleScript.

Мне неясно, почему вы включили петлю repeat.

Цель сценария - открыть новую вкладку терминала на моем Mac и автоматически запускать «screen -r $ HOST» в каждом новом терминале до конца списка хостов в документе hosts2.txt. Каждый хост указан в отдельной строке. Это повторяется 2 раза, поскольку в текстовом документе указаны только 2 хоста

Это не имеет смысла, учитывая, что вы реализовали цикл 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 не является командой Terminal . Это команда, принадлежащая стандартным дополнениям AppleScript. Поэтому, если бы остальная часть вашего кода работала, и он попал в эту команду, Terminal ничего бы не выполнил. Вместо этого сценарии оболочки будут работать в фоновом режиме без реальной оболочки, так что это не очень хорошо для вас.

Ваша команда: do script.

К сожалению, действительно кажется, что, по крайней мере, в High Sierra, команды AppleScript для создания новых вкладок и окон в Terminal больше не работают, поэтому я могу понять, почему вы обратились Системные события , чтобы создать вкладку так, как у вас есть. К счастью, в этом нет необходимости, и ваши многочисленные команды activate: do script автоматически запустят Terminal и по умолчанию выполнят скрипт на новой вкладке.

Поэтому единственная команда 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
0 голосов
/ 04 января 2019

В вашем коде есть опечатка.

Строка tell application "Terminal" activate должна быть tell application "Terminal" to activate.

Расширение переменной также не работает в одинарных кавычках в 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

Редактировать: Я думаю, что на самом деле есть еще одна проблема: при установке переменной на строку в applecript строка должна быть заключена в кавычки. Таким образом, set host to $HOST вызывает ошибку, поскольку интерпретирует значение $HOST ("pulsar" или "dev") как команду, которую невозможно найти / выполнить; вместо этого оно должно быть set host to \"$HOST\". Я изменил это выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...