(New) Sending a command to Terminal, via applescript

Hi,

Very new to this, I have a simple q that should solve all my problems. I’ve cobbled
the script below, to open 2 Terminal windows. I’d like to run some commands
in them. Because there will be programs running in the Terminal windows that need
their own input, I just want to know how I can send text to the terminal window, followed
by a carriage return. The problem with what I have below, is that the results of the “ls -l”
command is shown in the applescript editor window, not the Terminal window itself.

(also if anyone knows how to assign a title to the window, that would be cool).

Thanks

tell application "Terminal"
	
	do script ""
	do script ""
	
	set the background color of window 1 to "green"
	set the normal text color of window 1 to "black"
	set the number of columns of window 1 to 80
	set the number of rows of window 1 to 24
	set the position of window 1 to {1150, 20}
	
	set the background color of window 2 to "yellow"
	set the normal text color of window 2 to "black"
	set the number of columns of window 2 to 80
	set the number of rows of window 2 to 24
	set the position of window 2 to {1150, 400}
	
end tell

tell window 1
	do shell script "ls -l"
end tell

This seems to work for me:

tell application "Terminal"
	
	do script ""
	do script ""
	
	set the background color of window 1 to "green"
	set the normal text color of window 1 to "black"
	set the number of columns of window 1 to 80
	set the number of rows of window 1 to 24
	set the position of window 1 to {1150, 20}
	
	set the background color of window 2 to "yellow"
	set the normal text color of window 2 to "black"
	set the number of columns of window 2 to 80
	set the number of rows of window 2 to 24
	set the position of window 2 to {1150, 400}
	
end tell

tell application "Terminal"
	tell window 1
		activate
		tell application "System Events"
			keystroke "ls -l" & (ASCII character (10))
		end tell
	end tell
end tell

-Dan

Ah - and a little more fiddling sets the header:

tell application "Terminal"
	
	do script ""
	do script ""
	
	set the background color of window 1 to "green"
	set the normal text color of window 1 to "black"
	set the number of columns of window 1 to 80
	set the number of rows of window 1 to 24
	set the position of window 1 to {1150, 20}
	
	set the background color of window 2 to "yellow"
	set the normal text color of window 2 to "black"
	set the number of columns of window 2 to 80
	set the number of rows of window 2 to 24
	set the position of window 2 to {1150, 400}
	
end tell

tell application "Terminal"
	tell window 1
		set custom title to "ABC"
		set title displays custom title to true
		set title displays shell path to false
		activate
		tell application "System Events"
			keystroke "ls -l" & (ASCII character (10))
		end tell
	end tell
end tell

I learned something…thanks.

  • Dan

That’s because you’re using the “do shell script” command. That command has nothing to do with the Terminal. In fact, it’s very purpose is to get the results of a script without using the Terminal. If you want to script the Terminal, then you need to use Terminal’s “do script” command.

Try something like this:

tell application "Terminal"
	activate
	do script ""
	do script ""
	
	tell window 1
		set background color to "green"
		set normal text color to "black"
		set number of columns to 80
		set number of rows to 24
		set position to {1150, 20}
		set custom title to "ABC"
		set title displays custom title to true
		set title displays shell path to false
		set title displays device name to false
		set title displays shell path to false
		set title displays window size to false
		set title displays file name to false
	end tell
	
	tell window 2
		set the background color to "yellow"
		set the normal text color to "black"
		set the number of columns to 80
		set the number of rows to 24
		set the position to {1150, 400}
		set custom title to "XYZ"
		set title displays custom title to true
		set title displays shell path to false
		set title displays device name to false
		set title displays shell path to false
		set title displays window size to false
		set title displays file name to false
	end tell
	
	do script "ls -l" in window 1
	do script "echo 'Hello, World!'" in window 2
end tell

Hi,

Ah, I see. Perfect, exactly what I needed…thanks to both of you, I appreciate it!

Sorry, thought I had it, but one followup. In dant’s second script, the ‘tell application terminal’ will always write to window1…even if I change it to “tell window 2”. I need to tell both windows different things, so I need to go back and forth. Below is a better description of my problem.

tell application "Terminal"
	
	do script ""
	do script ""
	
	set the background color of window 1 to "green"
	set the normal text color of window 1 to "black"
	set the number of columns of window 1 to 80
	set the number of rows of window 1 to 24
	set the position of window 1 to {1150, 20}
	
	set the background color of window 2 to "yellow"
	set the normal text color of window 2 to "black"
	set the number of columns of window 2 to 80
	set the number of rows of window 2 to 24
	set the position of window 2 to {1150, 400}
	
end tell

tell application "Terminal"
	tell window 1
		set custom title to "ABC"
		set title displays custom title to true
		set title displays shell path to false
		activate
		tell application "System Events"
			keystroke "ls" & (ASCII character (10))
		end tell
	end tell
end tell

tell application "Terminal"
	tell window 2
		set custom title to "XYZ"
		set title displays custom title to true
		set title displays shell path to false
		activate
		tell application "System Events"
			keystroke "ls -al" & (ASCII character (10))
		end tell
	end tell
end tell

Sorry to nag…any thoughts?

You’re using System Events to press keys in what ever window (or whatever) is in front. If you’re want those keys to go somewhere specific, then you have to tell System Events that (the tell statement you mentioned is used by Terminal, not System Events).

However, that should all be moot, as “do script” should (see my script) do whatever you want. unless you’re having problems with something specific in your situation. Seeing how you never mentioned exactly what you’re trying to do, I don’t know what else to do for you. (I thinking it may be something more complicated then “ls.”)

Sorry, I don’t think I’ve explained it very well. I am using both methods to give input
to the windows. I do need to to a couple script commands in each, at first. However, there
comes a time when shell scripts begin running in the windows…and they are waiting for
the user to enter text. When I try to use the ‘do script’ command for this needed input,
they aren’t entered.

Below is a better example of what I’m trying to do. The “poo” and “pee” inputs are
meaningless to the shell, but very meaningful to the shell script that will be running
in them. I want to tell window2, “pee”. There are most certainly better ways to do
what I’m trying to do, but I need a quick fix for now.

tell application "Terminal"
	do script ""
	do script ""
	
	set the background color of window 1 to "green"
	set the normal text color of window 1 to "black"
	set the number of columns of window 1 to 80
	set the number of rows of window 1 to 24
	set the position of window 1 to {1150, 20}
	
	set the background color of window 2 to "yellow"
	set the normal text color of window 2 to "black"
	set the number of columns of window 2 to 80
	set the number of rows of window 2 to 24
	set the position of window 2 to {1150, 400}
	
	do script "echo 'Hello world'" in window 1
	do script "echo 'Hello world2'" in window 2
	
	tell application "Terminal"
		tell window 1
			set custom title to "ABC"
			set title displays custom title to true
			set title displays shell path to false
			activate
			tell application "System Events"
				keystroke "poo in window1" & (ASCII character (10))
			end tell
		end tell
	end tell
	
	tell application "Terminal"
		tell window 2
			set custom title to "XYZ"
			set title displays custom title to true
			set title displays shell path to false
			activate
			tell application "System Events"
				keystroke "pee in window2" & (ASCII character (10))
			end tell
		end tell
	end tell
end tell

Hopefully this is closer to what you’re looking for.

tell application "Terminal"
	activate
	close every window
	
	do script ""
	tell front window
		set background color to "green"
		set normal text color to "black"
		set number of columns to 80
		set number of rows to 24
		set position to {1150, 20}
		set custom title to "ABC"
		set title displays custom title to true
		set title displays shell path to false
		set title displays device name to false
		set title displays shell path to false
		set title displays window size to false
		set title displays file name to false
	end tell
	
	do script ""
	tell front window
		set the background color to "yellow"
		set the normal text color to "black"
		set the number of columns to 80
		set the number of rows to 24
		set the position to {1150, 400}
		set custom title to "XYZ"
		set title displays custom title to true
		set title displays shell path to false
		set title displays device name to false
		set title displays shell path to false
		set title displays window size to false
		set title displays file name to false
	end tell
	
	do script "wc -w" in window "ABC"
	do script "wc -w" in window "XYZ"
end tell

tell application "System Events"
	tell process "Terminal"
		tell window "XYZ"
			keystroke "pee" & (ASCII character 10)
			keystroke "d" using control down
		end tell
		
		tell window "ABC"
			perform action "AXRaise"
			
			keystroke "poo" & (ASCII character 10)
			keystroke "d" using control down
		end tell
	end tell
end tell

Hi,

Thanks for looking at this…I appreciate the help.

When I run the script you have above, I get a “Applescript error: system events got
an error: NSReceiverEvaluationScriptError: 4” error box, when it gets to
the “perform action “AXRaise”” line. If I comment it out, both ‘pee’ and ‘poo’ go
into window XYZ.

This is basically what I need it to do, tho. I’d like to be able to go back
and forth…that is, I need to enter ‘pee’ into XYZ, then enter ‘poo’ into ABC, then
enter ‘neenee’ into XYZ, etc.

Thanks for your time.

Well, so much for that idea. FWIW, if you comment out that line, then it should all go into window XYZ.

I was using “perform action “AXRaise”” to bring that window to the front, so that the keys would be entered there.

Why don’t you let us know what version of OS X you’re using, and I’ll try to get back to this soon.

Jacques’ script works for me, looks like it is just what I need.

I’m using OS X 10.4.3. Thanks for all the help, it looks like these forums will be a great
aid for me to get better at applescript.

FWIW, you could change it slightly:

tell application "Terminal"
	activate
	
	close every window
	do script ""
	tell front window
		set background color to "green"
		set normal text color to "black"
		set number of columns to 80
		set number of rows to 24
		set position to {1150, 20}
		set custom title to "ABC"
		set title displays custom title to true
		set title displays shell path to false
		set title displays device name to false
		set title displays shell path to false
		set title displays window size to false
		set title displays file name to false
	end tell
	
	do script ""
	tell front window
		set the background color to "yellow"
		set the normal text color to "black"
		set the number of columns to 80
		set the number of rows to 24
		set the position to {1150, 400}
		set custom title to "XYZ"
		set title displays custom title to true
		set title displays shell path to false
		set title displays device name to false
		set title displays shell path to false
		set title displays window size to false
		set title displays file name to false
	end tell
end tell

tell application "Terminal" to tell window "ABC" to set frontmost to true
tell application "System Events" to keystroke "poo" & (ASCII character 10)

tell application "Terminal" to tell window "XYZ" to set frontmost to true
tell application "System Events" to keystroke "pee" & (ASCII character (10))

tell application "Terminal" to tell window "ABC" to set frontmost to true
tell application "System Events" to keystroke "whatever" & (ASCII character 10)

You could also replace those last lines with a handler:

typeInTerminal("ABC", "pee" & (ASCII character 10))
typeInTerminal("XYZ", "poo" & (ASCII character 10))
typeInTerminal("ABC", "whatever" & (ASCII character 10))

on typeInTerminal(theWindow, theText)
	tell application "Terminal" to tell window theWindow to set frontmost to true
	tell application "System Events" to keystroke theText
end typeInTerminal

Hi,

Great, thanks again.

(In case anyone gets bored and feels like throwing me another bone, I’m starting to search
on how to do the next phase of my project. I need to:

  • Launch VirtualPC
  • Launch a program sitting on the Windows XP desktop
  • Create a pop-up window on the Mac desktop that says, “Click ok when finished
    working with .”
  • When user clicks the ‘ok’, run the applescript program from above.

Looking at creating an automator workflow, or applescript, or a combo of both. So far
I don’t seem to be hitting on the correct search terms to find examples of launching
a program from the xp desktop, but I’m sure they are out there somewhere.)

Thanks again for all the help on this, its been a huge help.

Great, I got exactly what I need and it works perfectly. Thanks very much for everyone’s
help!