Run script in tabs in Terminal in High Sierra - terminal

This AppleScript stopped working in High Sierra and returns the error
"error "Terminal got an error: Can’t get tab 2 of window 1." number -1728 from tab 2 of window 1"
I'm not that good with scripting so any help would be appreciated.
tell application "Terminal"
activate
do script
do script "rsync -avCP --progress --stats /Volumes/TERRI1/DCIM/NORMAL/ /Volumes/DCArchive/Vids" in tab 1 of front window
my makeTab()
do script "rsync -avCP --progress --stats /Volumes/TERRI2/DCIM/NORMAL/ /Volumes/DCArchive/Vids" in tab 2 of front window
my makeTab()
do script "rsync -avCP --progress --stats /Volumes/TERRI3/DCIM/NORMAL/ /Volumes/DCArchive/Vids" in tab 3 of front window
my makeTab()
do script "rsync -avCP --progress --stats /Volumes/TERRI4/DCIM/NORMAL/ /Volumes/DCArchive/Vids" in tab 4 of front window
end tell
on makeTab()
tell application "System Events" to keystroke "t" using {command down} delay 0.2
end makeTab

After much Googling and trial and error this works.
tell application "Terminal"
activate
do script
do script "rsync -avCP --progress --stats /Volumes/TERRI1/DCIM/NORMAL/ /Volumes/DCArchive/Vids" in tab 1 of front window
my makeTab()
do script "rsync -avCP --progress --stats /Volumes/TERRI2/DCIM/NORMAL/ /Volumes/DCArchive/Vids" in selected tab of front window
my makeTab()
do script "rsync -avCP --progress --stats /Volumes/TERRI3/DCIM/NORMAL/ /Volumes/DCArchive/Vids" in selected tab of front window
my makeTab()
do script "rsync -avCP --progress --stats /Volumes/TERRI4/DCIM/NORMAL/ /Volumes/DCArchive/Vids" in selected tab of front window
end tell
on makeTab()
tell application "System Events" to keystroke "t" using {command down}
delay 0.2
end makeTab

Related

How to execute shell script command in other terminal window

i have a quick question. I just wonder how i can execute command in shell script. Code should checking if python script is running, if not i want to run it again but in another terminal window. Shell code below.
while :
do
if pgrep -f "python instagram_bot.py" &>/dev/null; then
echo "it is already running"
sleep 1
else
python instagram_bot.py
fi
done
I'm using macOS system
In else statement i just wondering it is possible to execute command that open new terminal and run python script.
Thanks for any help, Best, Kacper
Assuming you are using Terminal on macOS, you can run:
osascript -e 'tell application "Terminal" to activate' \
-e 'tell application "System Events" to keystroke "n" using {command down}' \
-e 'tell application "Terminal" to do script "python instagram_bot.py" in front window'
You can start Terminal by using a "Spotlight search" by typing ⌘Space and typing "Terminal" and hitting Enter as soon as it guesses "Terminal.app".
Then, at the top-left of the screen, click Shell -> New Window and you will see that the shortcut for a new window is ⌘n. That's why the osascript above does keystroke "n" using {command down}' - it starts a new window.

How to close a Terminal tab using AppleScript?

I'm using AppleScript to open PostgreSQL in a Terminal tab like this:
#!/bin/bash
function new_tab() {
TAB_NAME=$1
COMMAND=$2
osascript \
-e "tell application \"Terminal\"" \
-e "tell application \"System Events\" to keystroke \"t\" using {command down}" \
-e "do script \"printf '\\\e]1;$TAB_NAME\\\a'; $COMMAND\" in front window" \
-e "end tell" > /dev/null
}
new_tab "PostgreSQL" "postgres -D /usr/local/var/postgres"
Running this script from the Terminal will open a new tab with PostgreSQL server inside. So at the end of the execution I'll have 2 tabs: the first one which was used to run the script, and the second one containing the server.
How can I close the first one?
This is my try:
osascript -e "tell application \"Terminal\" to close tab 1 of window 1"
But I get this error message:
execution error: Terminal got an error: tab 1 of window 1 doesn’t
understand the “close” message. (-1708)
You can try something like this:
tell application "Terminal"
activate
tell window 1
set selected tab to tab 1
my closeTabOne()
end tell
end tell
on closeTabOne()
activate application "Terminal"
delay 0.5
tell application "System Events"
tell process "Terminal"
keystroke "w" using {command down}
end tell
end tell
end closeTabOne
One way to do it is like this:
osascript \
-e "tell application \"Terminal\"" \
-e "do script \"exit\" in tab 1 of front window" \
-e "end tell" > /dev/null
But Terminal must be configured to close the window when the shell exits.
Anyone has a solution which does not need to do this?
This will close the active tab only:
tell application "Terminal" to close (get window 1)
To determine the tab’s window, you can parse the error message you get when trying to access the still non-existing window property of the tab. The error message usually contains the window's id with which you can reference the window.
As your question is 5 years old, I’ll finish my answer with example code that can be run in the Script Editor instead of a bash script which makes it hard to read.
tell application "Terminal"
-- Perform command
set theTab to do script "echo 'Hello World'"
try
-- Try to get the tab's window (this should fail)
set theWindow to window of theTab
on error eMsg number eNum
if eNum = -1728 then
(*
The error message should look like this:
Terminal got an error: Can’t get window of tab 1 of window id 6270.
*)
-- Specify the expected text that comes before the window id
set windowIdPrefix to "window id "
-- Find the position of the window id
set windowIdPosition to (offset of windowIdPrefix in eMsg) + (length of windowIdPrefix)
-- Get the window id (omitting the period and everything else after)
set windowId to (first word of (text windowIdPosition thru -1 of eMsg)) as integer
-- Store the window object in a variable
set theWindow to window id windowId
else
-- Some other error occurred; raise it
error eMsg number eNum
end if
end try
close theWindow
end tell
I think the key is to get the id of front window.
tell application "Terminal"
do script "pwd"
set myID to id of front window
close window id myID
end tell

Using AppleScript editor to input multiple commands in terminal

So i'm trying to write a simple script that opens terminal, ssh onto a server and does stuff while it's there.
tell application "Terminal"
Activate
do script "cd documents"
delay 2
do script "ssh private key user#server"
delay 6
do script "while true; do curl..."
end tell
How do i get it all in one terminal tab?
Currently it opens separate windows for each command
Try:
tell application "Terminal"
reopen
activate
do script "echo \"commmand one\"" in window 1
do script "echo \"commmand two\"" in window 1
end tell
Another way is to use semicolon to concatenate two commands, like this:
tell application "Terminal"
activate
do script "echo \"commmand one\"" & " ; " & "echo \"commmand two\""
end tell
I used & symbol to demo concatenation in case the "echo \"commmand one\"" is a variable.
tell application "Terminal"
reopen
activate
delay 1
do script "cd ~/Projects" in front window
do script "ls -al" in front window
do script "date" in front window
tell application "System Events" to keystroke "t" using {command down}
delay 1
do script "cd ~/Projects/react-app" in front window
do script "ls -al" in front window
end tell

Have a script wait until the last script is complete

I have a script that has two apple scripts that open a new tab and do a command. I want the second apple script to wait until the first apple script's command line action is completed. I would rather not have to only to a sleep for x long, before it continues.
Is there a way that I can do this?
Here is what I have:
osascript -e 'tell application "Terminal" to activate' \
-e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down' \
-e 'tell application "Terminal" to do script "cd '$current_dir'" in selected tab of the front window' \
-e 'tell application "Terminal" to do script "./my_script arg1" in selected tab of the front window'
------ Wait until this process is finished -------
osascript -e 'tell application "Terminal" to activate' \
-e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down' \
-e 'tell application "Terminal" to do script "cd '$current_dir'" in selected tab of the front window' \
-e 'tell application "Terminal" to do script "./my_script different_arg1" in selected tab of the front window'
You can check the busy property of a window or tab:
tell application "Terminal"
set w to do script "sleep 1"
repeat
delay 0.1
if not busy of w then exit repeat
end repeat
end tell
osascript -e 'on run {a}
tell application "Terminal"
activate
tell application "System Events" to keystroke "t" using command down
do script "cd " & quoted form of a & "; sleep 1" in window 1
repeat
delay 0.1
if not busy of window 1 then exit repeat
end repeat
tell application "System Events" to keystroke "t" using command down
do script "cd " & quoted form of a & "; sleep 1" in window 1
end tell
end run' /tmp

Open xterm telnet connection (Mac OS X)

I have been trying to get this script right for hours and came pretty far, but i'm stuck by passing commands to the X11 xterm window.
I need a connection to an xterm telnet server. This is the normal procedure:
open Terminal
type the command: xterm -fa Monaco -fs 12 (This opens an X11 window, with a bigger font)
in the new xterm window i type: telnet -l username server ip
this opens the telnet connection and prompts for the password
because some users w/o terminal knowledge have to have access to this connection i tried several approaches to write a script that would run on a Mac. And open the connection to let users work in the opened telnet window. I ended up with using AppleScript for that, and wrote the following script:
tell application "X11"
activate
end tell
tell application "System Events"
tell process "X11"
tell menu bar 1
tell menu "Applications"
click menu item "Terminal"
tell window 1
run
do script "xterm -fa Monaco -fs 12"
delay 2
do script "telnet -l meister 192.169.25.1"
end tell
end tell
end tell
end tell
end tell
But unfortunately this doesn't work. It only opens an X11 xterm window, w/o the bigger fonface, and w/o the terminal command, it is just an empty window.
Does someone of you have a idea how i could change the script so it works, or maybe there is a way to do it with some other type of script rather that AppleScript?
Thank you very much for your help in advance!
First, to launch the xterm just do this:
do shell script "xterm -fa Monaco -fs 12 -wf"
This will automatically launch X11 if needed.
Depending on your system, /usr/X11/bin may not be on the path, so you may want to do this instead:
do shell script "/usr/X11/bin/xterm -fa Monaco -fs 12 -wf"
And if you want xterm to run a command instead of just opening a shell, use the -e parameter:
do shell script "/usr/X11/bin/xterm -fa Monaco -fs 12 -e telnet -l meister 192.169.25.1"
If the telnet command fails, the xterm window will close instantly; to debug that, add a "-hold" before "-e".
Since you asked about "some other type of script rather than apple script", the same thing is obviously a one-liner in bash, two with the shebang:
#!/bin/sh
/usr/X11/bin/xterm -fa Monaco -fs 12 -e telnet -l meister 192.169.25.1
If you save that as "doit" and "chmod +x doit", you can run it from the Terminal as "./doit".
Or, if you want it double-clickable in Finder, rename it to "doit.command".
Try:
tell application "X11"
activate
tell application "System Events" to tell process "X11"
click menu item "Terminal" of menu 1 of menu bar item "Applications" of menu bar 1
delay 0.5
keystroke "xterm -fa Monaco -fs 12"
delay 0.5
keystroke return
delay 0.5
keystroke "telnet -l meister 192.169.25.1"
delay 0.5
keystroke return
end tell
end tell

Resources