Sending commands and strings to Terminal.app with Applescript

MacosTerminalApplescript

Macos Problem Overview


I want to do something like this:

tell application "Terminal"
activate
do script "ssh [email protected]"
-- // write user's password
-- // write some linux commands to remote server
end tell

For example to log in to the server, enter the password, and then login to mysql and select a DB.
I type that every day and it would be really helpful to bundle it into a script.

Also, is there a reference of what commands, properties, functions, etc. do applications (Terminal, Finder, etc) have available to use within Applescript? thanks!

EDIT: Let me clear this up: I don't want to do several 'do script' as I tried and doesn't work. I want to open a Terminal window, and then emulate a human typing in some characters and hitting enter. Could be passwords, could be commands, whatever, just sending chars to the Terminal which happens to be running ssh. I tried keystroke and doesn't seem to work.

Macos Solutions


Solution 1 - Macos

First connect to the server and wait for 6 seconds (you can change that) and then execute whatever you need on the remote server using the same tab

tell application "Terminal"
   set currentTab to do script ("ssh user@server;")
   delay 6
   do script ("do something remote") in currentTab
end tell

Solution 2 - Macos

As EvanK stated each do script line will open a new window however you can run
two commands with the same do script by separating them with a semicolon. For example:

tell application "Terminal"
	do script "date;time"
end tell

But the limit appears to be two commands.

However, you can append "in window 1" to the do script command (for every do script after the first one) to get the same effect and continue to run as many commands as you need to in the same window:

tell application "Terminal"
	do script "date"
	do script "time" in window 1
	do script "who" in window 1
end tell


Note that I just used the who, date, and time command as an example...replace with whatever commands you need.

Solution 3 - Macos

Here's another way, but with the advantage that it launches Terminal, brings it to the front, and creates only one window.

I like this when I want to be neatly presented with the results of my script.

tell application "Terminal"
    activate
    set shell to do script "echo 1" in window 1
    do script "echo 2" in shell
    do script "echo 3" in shell
end tell

Solution 4 - Macos

How about this? There's no need for key codes (at least in Lion, not sure about earlier), and a subroutine simplifies the main script.

The below script will ssh to localhost as user "me", enter password "myPassw0rd" after a 1 second delay, issue ls, delay 2 seconds, and then exit.

tell application "Terminal"
	activate
	my execCmd("ssh me@localhost", 1)
	my execCmd("myPassw0rd", 0)
	my execCmd("ls", 2)
	my execCmd("exit", 0)
end tell
on execCmd(cmd, pause)
	tell application "System Events"
		tell application process "Terminal"
			set frontmost to true
			keystroke cmd
			keystroke return
		end tell
	end tell
	delay pause
end execCmd

Solution 5 - Macos

You don't need to "tell" Terminal to do anything. AppleScript can do shell scripts directly.

set theDir to "~/Desktop/"
do shell script "touch " & theDir &"SomeFile.txt"

or whatever ...

Solution 6 - Macos

Why don't use expect:

tell application "Terminal"
	activate
	set currentTab to do script ("expect -c 'spawn ssh user@IP; expect \"*?assword:*\"; send \"MySecretPass
\"; interact'")
end tell

Solution 7 - Macos

The last example get errors under 10.6.8 (Build 10K549) caused by the keyword "pause".

Replacing it by the word "wait" makes it work:

tell application "Terminal"
    activate
    my execCmd("ssh me@localhost", 1)
    my execCmd("myPassw0rd", 0)
    my execCmd("ls", 2)
    my execCmd("exit", 0)
end tell

on execCmd(cmd, wait)
    tell application "System Events"
       tell application process "Terminal"
          set frontmost to true
          keystroke cmd
          keystroke return
       end tell
    end tell

    delay wait
end execCmd

Solution 8 - Macos

Your question is specifically about how to get Applescript to do what you want. But, for the particular example described, you might want to look into 'expect' as a solution.

Solution 9 - Macos

Kinda related, you might want to look at Shuttle (http://fitztrev.github.io/shuttle/), it's a SSH shortcut menu for OSX.

Solution 10 - Macos

I could be mistaken, but I think Applescript Terminal integration is a one-shot deal...That is, each do script call is like opening a different terminal window, so I don't think you can interact with it at all.

You could copy over the SSH public keys to prevent the password prompt, then execute all the commands joined together (warning: the following is totally untested):

tell application "Terminal"
    activate
    do script "ssh [email protected] '/home/jdoe/dosomestuff.sh && /home/jdoe/dosomemorestuff.sh'"
end tell

Alternatively, you could wrap the ssh and subsequent commands in a shell script using Expect, and then call said shell script from your Applescript.

Solution 11 - Macos

set up passwordless ssh (ssh-keygen, then add the key to ~/.ssh/authorized_keys on the server). Make an entry in ~/.ssh/config (on your desktop), so that when you run ssh mysqlserver, it goes to user@hostname... Or make a shell alias, like gotosql, that expands to ssh user@host -t 'mysql_client ...' to start the mysql client interactively on the server.

Then you probably do need someone else's answer to script the process after that, since I don't know how to set startup commands for mysql.

At least that keeps your ssh password out of the script!

Solution 12 - Macos

Petruza,

Instead of using keystroke use key code.
The following example should work for you.

tell application "System Events"
	tell application process "Terminal"
		set frontmost to true
		key code {2, 0, 17, 14}
		keystroke return
	end tell
end tell

The above example will send the characters {d a t e} to Terminal and then
keystroke return will enter and run the command. Use the above example
with whatever key codes you need and you'll be able to do what you're trying to do.

Solution 13 - Macos

what about something like this:

tell application "Terminal"

	activate
	do shell script "sudo dscl localhost -create /Local/Default/Hosts/cc.josmoe.com IPAddress 127.0.0.1"
	do shell script "sudo dscl localhost -create /Local/Default/Hosts/cc.josmos2.com IPAddress 127.0.0.1"

end tell

Solution 14 - Macos

As neat solution, try-

$ open -a /Applications/Utilities/Terminal.app  *.py

or

$ open -b com.apple.terminal *.py

For the shell launched, you can go to Preferences > Shell > set it to exit if no error.

That's it.

Solution 15 - Macos

I built this script. It is in Yosemite and it is bash script using AppleScript to choose a list of users for SSH servers. Basically you define an IP and then the user names.. when the application launches it asks who you want to login in as.. the SSH terminal is launched and logged in prompting a password...

(***
 * --- --- --- --- ---
 * JD Sports Fashion plc
 * Apple Script
 * Khaleel Mughal
 * --- --- --- --- ---
 * #SHELLSTAGINGSSHBASH
 * --- --- --- --- ---
***)

set stagingIP to "192.162.999.999"

set faciaName to (choose from list {"admin", "marketing", "photography_cdn"})

if faciaName is false then
	display dialog "No facia was selected." with icon stop buttons {"Exit"} default button {"Exit"}
else
	set faciaName to (item 1 of faciaName)
	
	tell application "Terminal"
		activate
		do script "ssh " & faciaName & "@" & stagingIP & ""
	end tell
	
end if

I highly recommend though; Nathan Pickmans post above about Shuttle (http://fitztrev.github.io/shuttle/).. a very smart and simple application.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPetruzaView Question on Stackoverflow
Solution 1 - MacosCRPView Answer on Stackoverflow
Solution 2 - Macosuser225057View Answer on Stackoverflow
Solution 3 - MacosDanView Answer on Stackoverflow
Solution 4 - MacosAllen RobelView Answer on Stackoverflow
Solution 5 - Macosuser1984702View Answer on Stackoverflow
Solution 6 - MacosK. BiermannView Answer on Stackoverflow
Solution 7 - Macosuser1019711View Answer on Stackoverflow
Solution 8 - MacospizzaFaceView Answer on Stackoverflow
Solution 9 - MacosNathan PitmanView Answer on Stackoverflow
Solution 10 - MacosEvanKView Answer on Stackoverflow
Solution 11 - MacosPeter CordesView Answer on Stackoverflow
Solution 12 - Macosuser225057View Answer on Stackoverflow
Solution 13 - MacosjoeyView Answer on Stackoverflow
Solution 14 - MacosMohammad Shahid SiddiquiView Answer on Stackoverflow
Solution 15 - MacosTheBlackBenzKidView Answer on Stackoverflow