I have written an AppleScript that starts my shell by typing in the commands in the terminal. But I want to test the shell and so I want to save the command result in a variable. This is my code:
#!/bin/bash
osascript <<EOF
tell application "System Events"
keystroke "cd /Users/uwe/documents/coding/c/pshell"
delay 0.5
keystroke return
delay 0.5
keystroke "make compile_and_run"
delay 1
keystroke return
delay 0.5
keystroke "bash /Users/uwe/documents/coding/c/pshell/tests/user_test.sh"
delay 0.5
keystroke return
key code 126
delay 0.5
set arrow_result to keystroke return // this is where I want to save the output
display dialog arrow_result // it says there is no variable called 'arrow_result'
end tell
EOF
If its possible I could also store the result in a bash variable but I don't think that that works
You can of course send keystroke commands and then get the text content of the terminal window (and then parse it) with the following command:
set arrow_result to value of text field 1 of scroll area 1 of splitter group 1 of window 1 of process "Terminal"
But why be so perverted. There is no need to use Terminal, System Events and GUI scripting to complete your task. Instead, use the most powerful tool in the AppleScript language, the do shell script command:
#!/bin/bash
osascript <<EOF
set arrow_result to(do shell script "cd /Users/uwe/documents/coding/c/pshell
make compile_and_run
bash /Users/uwe/documents/coding/c/pshell/tests/user_test.sh")
display dialog arrow_result
EOF
NOTE: I tested my suggestion in the Terminal with following code:
osascript <<EOF
set arrow_result to do shell script "echo \"Hello, World!\""
display dialog arrow_result
EOF
Related
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.
I am trying to automate this process.
step 1: change system date to a specific date.
step 2: open an application.
step 3: change system date back to normal.
Now on Automator, I have three apple scripts placed like this.
on run {input, parameters}
tell application "Terminal"
do script with command "sudo date 082704002018"
activate
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
end run
on run {input, parameters}
tell application "Terminal"
do script with command "open -a applicationName"
activate
end tell
end run
on run {input, parameters}
tell application "Terminal"
do script with command "sudo ntpdate -u time.apple.com"
activate
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
end run
The problem is that Automator only runs the first code. I'm not sure how to make it run all the codes in order.
Sorry if this is a stupid question. I am completely new to automator and applescript.
Thank you
I'm not quite sure why you chose to use three separate AppleScripts. You can combine them all into one AppleScript as I have done in this following example. I'm not quite sure why you used the “activate” commands. I don't think they are necessary so I removed those lines of the code. Anyway, this following code should work for you…
tell application "Terminal"
do script with command "sudo date 082704002018"
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
tell application "Terminal"
do script with command "open -a applicationName"
delay 1
do script with command "sudo ntpdate -u time.apple.com"
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
Alternately, launching Terminal app to run shell scripts is not necessary all the time as you can run shell scripts in AppleScript by using the “do shell script” command. This following applescript code is your code using only eight lines of code.
do shell script "sudo date 082704002018"
tell application "System Events" to keystroke "mypassword" & return
delay 3
do shell script "open -a applicationName"
delay 1
do shell script "sudo ntpdate -u time.apple.com"
delay 1
tell application "System Events" to keystroke "mypassword" & return
If my versions of your code throw errors, it may be necessary to adjust the delay commands or re-insert the activate commands
If you are hell-bent on using your version of the code and three separate Applescripts, just remove the on run {input, parameters} and end run lines of code from each AppleScript and that should eliminate your problem
I'm trying to open terminal using apple script with a ready command but without executing it and allowing user to do this just by clicking enter (so I don't want to use tell Terminal to do script)
One of the approaches I used is using keystrokes:
tell application "Terminal" do script "echo Hi!"
keystroke "abc"
end tell
but it doesn't work for me. Any ideas?
I think you want to start Terminal and have a command all lined up ready in the Terminal ready for the user so he/she only has to press "Enter". If so, you can do this:
tell application "Terminal"
activate
delay 1
tell application "System Events"
keystroke "echo hi"
end tell
end tell
Then the user just has to press Enter and the command echo hi will execute.
it is hard to understand what you mean.
You can't for instance have the terminal wait for a user to click its window.
(But you can poll for a keystroke after the terminal window is opened.)
You'd have to use a dialog before your code, in order to make the user enter the terminal consciously.
display dialog "Press ok to enter the terminal" buttons {"Cancel","Enter"} cancel button 1 default button 2
Other than that, the way you'd need to use system events to send keystroke to the Terminal
tell application "System Events"
tell application process "Terminal"
keystroke "abcd"
end tell
end tell
You can poll for a keypress in the do script command to your terminal with this:
read -n 1 -s MYCHAR </dev/tty
This will force the user to press enter from a do script
a=`read`
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
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