How to send Ctrl+C to all iTerm2 tabs except the current in AppleScript? - applescript

I have this code that sends a specific command to all tabs including the current one, in iTerm2. But, sometimes, some tabs are stuck and I want to get them to a shell prompt before trying to execute the command. However, sending Ctrl+C to the current tab, will stop the script from continuing.
I want to send the kill signal to all other tabs but not the current one.
osascript \
-e 'tell application "iTerm"' \
-e " tell current window" \
-e ' repeat with aTab in tabs' \
-e ' tell aTab' \
-e ' repeat with asession in sessions' \
-e ' tell asession' \
-e ' tell application "System Events" to keystroke "c" using {control down}' \
-e ' end tell' \
-e ' end repeat' \
-e ' end tell' \
-e ' end repeat' \
-e ' end tell' \
-e 'end tell'
I tried conditioning "tell aTab" with "if aTab is not equal current tab", but that still didn't work.

The following example AppleScript code was tested in Script Editor under macOS Catalina and iTerm2, Build 3.3.12, and worked for me without issues as is, with the current window having multiple tabs each with a single session, and except for the tab that was the current tab when executed, stopped the running process in each tab.
tell application "iTerm"
activate
tell current window
set excludeTab to current tab
select tab 1
repeat with aTab in tabs
select aTab
if current tab is not equal to excludeTab then
tell current session
tell application "System Events" to ¬
key code 8 using {control down}
end tell
end if
end repeat
select excludeTab
end tell
end tell
Notes:
Instead of using osascript -e command on a script such as this, I'd highly recommend creating an executable file with a #!/usr/bin/osascript shebang and then just copy and paste the example AppleScript code into the executable file as is. This IMO is much easier to maintain and modify as needed then using osascript -e command on a script such as this.
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.

Related

iterm2 after upgrade does not open up profiles

I want to be able to type at command prompt
it2 myMachine and have a new session pop up with defaults for that profile in Iterm2.
The following used to work until upgrades, where $1 is the profile name...
osascript <<ENDSCRIPT
on run argv
tell application "iTerm"
activate
tell the first terminal
launch session "$1"
end tell
end tell
end run
ENDSCRIPT
71:79: syntax error: Expected class name but found identifier. (-2741)
I also am looking at straight osascript in bash. But new tab does not get command.
osascript -e "tell application \"Terminal\""
-e "tell application \"System Events\" to keystroke \"t\" using {command down}"
-e "do script \"cd $pwd; clear\" in front window"
-e "end tell"
I found all on iterm2 help pages... tell application "iTerm2" tell current window create tab with default profile end tell end tell There are many standard Applescript functions (e.g., to get the window's size and position) that are not documented here. create tab with default profile create tab with profile "name"

Applescript–execute multi line code

I have some apple script code:
tell application "System Events"
key code 97
end tell
How do i write the code as a osascript -e command in Terminal?
Everytime I try using \n or the such, I get errors. Sorry if I'm not being specific enough.
You have a couple of options:
Pass each line of the AppleScript code as a separate -e option:
osascript -e 'tell application "System Events"' -e 'key code 97' -e 'end tell'
Pipe the AppleScript code to osascript's STDIN:
osascript <<END
tell application "System Events"
key code 97
end tell
END
Oh, and you can also save AppleScript code as an executable shell script. Just add #!/usr/bin/osascript at the top of the code and save it as a plain text file:
#!/usr/bin/osascript
tell application "System Events"
key code 97
end tell
Other example:
open -a Terminal && \
sleep 2 && \
osascript -e 'activate application "Terminal"' -e 'tell application "System Events" to keystroke "q" using command down'
the first two lines are just to show the final goal, which is focus the Terminal window and quit it, sending Command+q
Actually -e option accepts new lines:
osascript -e '
tell application "System Events"
key code 97
end tell'

On osx, how to open new iterm terminal tab from one script then run command in that temrinal window

I am running osx. I have a script which runs the full stack then runs grunt at the end. I want to be able to separate running grunt in a separate terminal tab, i am using iterm.
I have tried something like
open -a Terminal "cd ~/dev/work/poc/user-interface/src/main/webapp; grunt"
any ideas?
This should do it for you (obviously change dir & command):
osascript -e '
tell app "iTerm"
activate
tell the first terminal
launch session "Default Session"
tell the last session
set name to "New Session"
write text "cd /usr/bin; ls"
end tell
end tell
end tell'
It's a slightly modified version of something I wrote to add iTerm support for RStudio.
Like this:
#!/bin/bash
osascript -e '
tell application "Terminal"
do script "date"
activate
end tell'
Replace date with whatever you want it to do.

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

How to distinct multiple java processes in AppleScript

I encounter a problem when writting osascript. I need to "tell" one java process (GUI) to do something but there are other java process with the same process name "java" (also GUI),
so my below sample code will not work for me:
osascript \
-e "tell application \"System Events\"" \
-e "tell process \"java\"" \
-e "click button \"MyButton\" of tab group 1 of window \"MyWindow\"" \
-e "end tell" \
-e "end tell"
So my question is how to distinct different java process in such scenario?
Based on your response to my comment, I would do something like the following. Note that I did not test this so you'll probably have to tweak it but it shows how you can check for those specific names. Good luck.
tell application "System Events"
set javaProcesses to processes whose name is "java"
repeat with aJavaProcess in javaProcesses
tell aJavaProcess
try
set windowName to name of window 1
set buttonNames to title of buttons of tab group 1 of window 1
if windowName is "Java Control Panel" and "Update Now" is in buttonNames then
click (first button of tab group 1 of window 1 whose title is "Update Now")
exit repeat
end if
end try
end tell
end repeat
end tell
EDIT: maybe you can get at the proper process like this...
tell application "System Events"
set javaIDs to unix id of processes whose name is "java"
repeat with i from 1 to count of javaIDs
set aJavaProcess to (first process whose unix id is (item i of javaIDs))
tell aJavaProcess
-- do the stuff in the tell block from the code above
end tell
end repeat
end tell

Resources