Using bash for loops in conjunction with embedded applescript for bash scripts

General Tech Learning Aids/Tools 2 years ago

0 2 0 0 0 tuteeHUB earn credit +10 pts

5 Star Rating 1 Rating

Posted on 16 Aug 2022, this text provides information on Learning Aids/Tools related to General Tech. Please note that while accuracy is prioritized, the data presented might not be entirely correct or up-to-date. This information is offered for general knowledge and informational purposes only, and should not be considered as a substitute for professional advice.

Take Quiz To Earn Credits!

Turn Your Knowledge into Earnings.

tuteehub_quiz

Answers (2)

Post Answer
profilepic.png
manpreet Tuteehub forum best answer Best Answer 2 years ago

 

I'm trying to get applescript to interact with the bash for loop that is a part of my code to keep from having to list each host manually and execute individual tell/end tell blocks for each host found in the hosts2.txt file.

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.

I've tried an all inclusive for loop, without the applescript "repeat 2 times" "end repeat" code that is shown below. It is repeating 2 times because there are only 2 hosts listed in the text document for testing purposes. Each time I have error output.

#!/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

What I expect to happen is for the code the execute opening new terminal tabs with screen -r for each host. Error output is below this line.

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)
profilepic.png
manpreet 2 years ago

There are a few issues with your script: some that stop it from working entirely; some that get it to do the wrong thing; and some that needn't have been there in the first place. There are couple of other answers that address some points, but neither of them appeared to test the script because there's a lot they don't address.

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

Then this line:

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

is not what you want. That will create an array out of individual words, not lines in the file. You want to use the read command, that reads a file line-by-line. You can structure a loop in this manner:

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

As @entraz has already pointed out, your use of single quotes will stop shell variables from being expanding within your osascript.

Then there is the AppleScript itself.

I'm unclear why you included a repeat loop.

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

This makes no sense, given that you implemented a bash loop in order to read the lines into the $HOST variable. Granted, you were reading words, not lines, but the AppleScript repeat is a head-scratcher. Bin it.

Then you have this:

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

That's approximately infinity times the number you need to tell Terminal to activate.

This line:

set host to $HOST

will throw an error for two reasons: firstly, host is taken as an existing name of a property in AppleScript's standard additions, so you can't go and set it to a new value; secondly, there are no quotes around $HOST, so it's not going to be recognised as a string. But, this is just for your learning, as we're actually going to get rid of that line completely.

Finally:

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

is wrong. do shell script is not a Terminal command. It's a command belonging to AppleScript's standard additions. Therefore, if the rest of your code worked, and it got to this command, Terminalwould execute nothing. Instead, the shell scripts would run in the background without an actual shell, so that's not much good to you.

The command you're after is do script.

Sadly, it does appear that, in High Sierra at least, the AppleScript commands to make new tabs and windows in Terminal no longer work, so I can see why you resorted to System Events to create a tab in the way that you have. Thankfully, that's not necessary, and nor are your multiple activatecommands: do script will automatically run Terminal and execute a script in a new tab by default.

Therefore, the only AppleScript command you need is this:

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

The Final Script

Putting this all together, here is the final hybrid script:

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

Alternatively

If you wanted to take the loop from bash and put it in AppleScript instead, you can do so like this, for which I'll use a heredoc (<<) to simplify the use of quotes and aid readability:

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 views   0 shares

No matter what stage you're at in your education or career, TuteeHub will help you reach the next level that you're aiming for. Simply,Choose a subject/topic and get started in self-paced practice sessions to improve your knowledge and scores.

tuteehub community

Join Our Community Today

Ready to take your education and career to the next level? Register today and join our growing community of learners and professionals.

tuteehub community