do shell script ("open -a Terminal.app")
tell application "Terminal"
do script cd_path in window 1
repeat with theItem in (items of command_list)
do script theItem in window 1
end repeat
end tell
It feeds the entire list directly into Terminal in one go. Terminal usually handles this okay, and holds off accepting the input for the next command until the one before it is done processing. But sometimes it gets a bit scrambled and trips itself up. Sometime it ends up skipping a few commands, then getting back on track and correctly running later ones.
I would ideally like to run one script, wait until that Terminal process is complete, then run the next one, wait until it is complete, etc. I don’t really care if this goes a bit slower, speed is not a concern here. Automation of the processes with good accuracy is much more important.
Any ideas for how to slow down feeding the commands to Terminal one at a time? Thx in advance!
I apologize for asking a question and then answering it, but I did some experimenting in the meantime and I have hit upon a decent solution: putting " && " between each script will make them wait until the process before it has finished. In my testing the last few hours this is working reliably. This means I have to smush all of the script calls together into one long string, with the " && " in between each script, rather than do “repeat with theItem” in Applescript. Then I pass the whole long string to Terminal in one go. Also, for some reason it does not run immediately, but leaves me at a weird "> " text prompt. When I type “exit” the scripts begin to run. So the new code looks like this:
set final_log to {}
repeat with xItem in (items of this_log)
try
set AppleScript's text item delimiters to {" #"}
set tItem to text item 1 of xItem
set uItem to text item 2 of xItem
set vItem to text item 3 of xItem
set wItem to "./script " & tItem & " --run-option " & vItem & " --run-option " & uItem & " && " as string
set end of final_log to wItem
set AppleScript's text item delimiters to oldDelims
on error
set AppleScript's text item delimiters to oldDelims
end try
end repeat
set final_text to final_log as string
set cd_path to ("cd " & quoted form of this_path) as text
do shell script ("open -a Terminal.app")
tell application "Terminal"
do script cd_path in window 1
do script final_text in window 1
do script "exit" in window 1
end tell
This is admittedly a niche application, but if anyone needs to run sequential shell scripts that must not interfere with each other, maybe this will be helpful. Cheers!
But I think you forgot about something relevant in working with TID‘s in general…
You want to use two flavors of them - the default and the custom ones but if you want to reset TID‘s to default after your custom or in case of an error you need to define them as default before defining them as custom.
Your Script asks for oldTID‘s but it won’t get them in case of a failure since you didn’t define what’s oldTID‘s - and to mention - it doesn’t even reset them during the operation when it runs successfully as well.
In general TID‘s are reset after a Script was run - successfully or not. But if an operation that’s working actively with TID‘s you always need to define them properly - especially in cases like the one your Script is sketching.
A single line based on this scheme should solve this: set {<var=oldTIDs>,<AS TID‘s>} to {<AS TID‘s>,<customTID>}
subtledoctor. Thanks for your post. I’ve been working to reacquaint myself with Bash, and I had forgotten about the && operator.
As regards the above issue, I wasn’t able to replicate the circumstance you describe, but I have to wonder if a few short delays might solve the issue. This working example did not need the delay on my M2 Mac mini, though.
do shell script ("open -a Terminal.app")
delay 0.5
tell application "Terminal"
do script "mkdir ~/Test && cd ~/Test && touch 'Test File.txt'" in window 1
end tell
I often run into unexpected behavior — especially with the Terminal app —
so, to keep things simple, I’ve made it a habit to always wait one second between operations.
Sometimes when launching a new Terminal session or creating a new window,
the zshpath_helper seems to lag a bit.
If a command runs before environment variables are fully loaded,
it might fail or behave oddly — unless you wait at least 0.2 seconds.
So, when executing commands in a freshly opened Terminal or a new window,
adding a short delay might help.
Just a thought — hope it’s useful to someone.
SCRIPT
tell application "Terminal" to launch
tell application "Terminal"
set refWindowID to (do script "\n\n")
end tell
repeat
tell application "Terminal"
tell refWindowID
log processes as list
set numCntProcesses to (count of processes) as integer
end tell
if numCntProcesses > 2 then
delay 0.1
else
exit repeat
end if
end tell
end repeat
LOG
tell application "Terminal"
do script "\n\n"
--> tab 1 of window id 4588
get processes of tab 1 of window id 4588
--> {"login", "-zsh", "path_helper"}
-->runing path_helper
(*login, -zsh, path_helper*)
-->some time (*login, -zsh, locale*) (*login, -zsh,-zsh*)
-->I believe all of these are called during the zsh startup process.
count every processes of tab 1 of window id 4588
--> 3
get processes of tab 1 of window id 4588
--> {"login", "-zsh"}
(*login, -zsh*)
count every processes of tab 1 of window id 4588
--> 2
end tell
I’m not very knowledgeable about the shell but is the ‘wait’ command not relevant to this problem?
wait [ job … ]
Wait for the specified jobs or processes. If job is not given then all currently active child processes are waited for. Each job can be either a job specification or the process ID of a job in the job table. The exit status from this command is that of the job waited for.
Thanks for the reply! The OldDelims variable is actually set earlier in the script and made global, so every subroutine can use it to reset the TIDs. (What I posted is just a small tidbit, the actual script is ~400 lines long.) It’s a good catch though!
As for using a timed delay in the Applescript itself and feed each “do script” to Terminal with delays: I am avoiding that because I don’t know how long each Terminal process will run. Some finish in less than one second; others take 10 minutes or more. With a 2-second delay i could easily still be passing a command to Terminal while it is working. That usually still works… but a delay at the Terminal level makes it more reliable.
“Wait” is a good idea - I didn’t know about that. But it sounds like it serves the same purpose as " && " and the latter seems to be working reliably.
This is all good feedback though! I hope if someone has a similar problem in the future they find guidance here.
As I mentioned, I’m not too familiar with the use of some shell features.
I would simply note that ‘&&’ can present a problem when you require something downstream to complete even if the script stops prematurely, eg ‘exit’ command.