Re: Do shell script on a remote machine
Re: Do shell script on a remote machine
- Subject: Re: Do shell script on a remote machine
- From: Sander Tekelenburg <email@hidden>
- Date: Sat, 7 Feb 2004 01:35:38 +0100
[My apologies for sending my initial reply off-list. I allowed the list
server to fool me again :(]
At 09:43 -0600 UTC, on 2004/02/06, John C. Welch wrote:
>
On 2/6/04 7:44 AM, "Sander Tekelenburg" <email@hidden> wrote:
>
>> On 2/5/04 2:39 PM, "Chris Janton" <email@hidden> wrote:
>
> [...]
>
>
>
>>> The "ssh hostname" method will work with many many many target systems.
>
>>> No Finder or loginwindow required on the remote end
>
>>
>
>> That's not going to work with do shell script terribly well.
>
>
>
> In what sense?
>
>
>
> set remoteID to "username"
>
> set remoteMac to "remote host name" -- or IP address
>
> do shell script "ssh -l " & remoteID & " " & remoteMac & " ls -alF"
>
>
I don't see it working for my needs, which involves running software update,
>
and being able to wait for it to return a result when it's finished.
I still don't see the problem. To try to understand, I baked a script[*] that
does just that: ssh into a remote machine to run softwareupdate (and
diskutil's repairPermissions before and after). I just ran it to apply the
Java 1.4.2 and Safari 1.2 update on a remote machine. It ran very smoothly -
no bumps.
Handling errors returned by do shell script can be a drag. For the script
below, I didn't bother looking into what errors might be returned by
softwareupdate. But I thought you wanted to do this to remote machines that
have no users logged in at the 'console'. AFAIK ssh is your only option then.
In any case, if security is an issue then ssh seems like a better choice than
'cleartext' remote AppleEvents.
>
That's
>
not easy with "do shell script", but it's easier than trying to concatenate
>
a dozen shell commands from the get go. Being able to do this via remote
>
events is going to be a lot easier than trying to deal with shell script
>
oddities. Keeping it to remote apple events allows me to use the keychain
>
for password storage.
My approach assumes having created a keypair and uploaded the public portion
of it to the remote machine. The unix equivalent of Keychain is called
ssh-agent (which may well preceed Apple's Keychain - I don't know). With the
GUI front-end for ssh-agent (available at
<
http://www.phil.uu.nl/~xges/ssh/>), which even helps you create your
keypair, it doesn't get any easier or "Mac-like".
>
Third party osax aren't needed, and in any event, I won't use them because I
>
need to be able to rely on consistent performance without dealing with
>
licensing of osaxen, terminology class, etc.
The only third-party OSAX I use is system.osax, which is free. In any case,
it isn't requiered.
[*] Here it is:
(* start script *)
set {done, restart_requiered, remoteID, remoteMac, installString,
remotePassphrase} to my GatherData()
if not done then
my DoUpdate(restart_requiered, remoteID, remoteMac, installString,
remotePassphrase)
end if
on GatherData()
set {done, restart_requiered, remoteID, remoteMac, installString,
remotePassphrase} to {false, false, "", "", "", ""}
set remoteMac to text returned of (display dialog "Provide the hostname or
IP address for the remote Mac" default answer "")
set remoteID to text returned of (display dialog "Provide your username
for " & remoteMac & return & "Note that the account must have administrator
rights!" default answer "")
try
set remotePassphrase to askPassword "Enter the passphrase for " &
remoteID & "@" & remoteMac -- requieres system.osax
on error
display dialog "It looks like you don't have system.osax installed. You
should only continue if you are 100% sure nobody is looking at your screen!"
& return & return & ,
"With system.osax this wouldn't be an issue. system.osax is free and
can be downloaded from <
http://osaxen.com>" buttons ,
{"Continue", "Quit"} default button 2 with icon 2
set theResult to the result
if theResult = "Continue" then
set remotePassphrase to text returned of (display dialog "Enter the
passphrase for " & remoteID & "@" & remoteMac default answer "")
else
tell me to quit
end if
end try
set remoteUpdate to (do shell script "ssh -l " & remoteID & " " &
remoteMac & " softwareupdate -l")
if remoteUpdate contains "Your software is up to date" then
display dialog "Software on " & remoteMac & " is up to date."
set done to true
else
set theResult to paragraphs 2 thru -1 of (my parse(remoteUpdate, ":"))
set itemCount to count items of theResult
set thisItem to 1
set updateList to {}
repeat until thisItem > itemCount
set theUpdate to (characters 6 thru -1 of (item thisItem of
theResult) as text)
set itsDescription to last word of (characters 2 thru -1 of (item
(thisItem + 1) of theResult) as text)
if last word of itsDescription = "restart" then
set theUpdate to theUpdate & " [restart]"
end if
copy theUpdate to end of updateList
set thisItem to thisItem + 2
end repeat
set ToBeInstalled to choose from list updateList with prompt "Select 1
or more items to update on " & remoteMac with multiple selections allowed
without empty selection allowed
set installString to ""
repeat with i in ToBeInstalled
if last word of i contains "restart" then
set restart_requiered to true
set installString to installString & ((characters 1 thru -11 of
i) as string) & " "
else
set installString to installString & ((characters 1 thru -1 of i)
as string) & " "
end if
end repeat
end if
return {done, restart_requiered, remoteID, remoteMac, installString,
remotePassphrase}
end GatherData
on DoUpdate(restart_requiered, remoteID, remoteMac, installString,
remotePassphrase)
try
-- first ensure permissions are OK
do shell script "ssh -l " & remoteID & " " & remoteMac & " diskutil
repairPermissions /"
-- apply update
do shell script "echo " & remotePassphrase & " | ssh -l " & remoteID &
" " & remoteMac & " sudo softwareupdate -i " & installString
if restart_requiered then
-- reboot remote machine
do shell script "echo " & remotePassphrase & " | ssh -l " & remoteID
& " " & remoteMac & " sudo shutdown -r now"
end if
try
-- ensure permissions are still OK
my RepairAgain(remoteID, remoteMac)
on error m number n
log {n, m}
display dialog (n as text) & return & return & (m as text)
end try
end try
end DoUpdate
on parse(aString, theDelimiter)
set {AppleScript's text item delimiters, oldTIDs} to {theDelimiter,
AppleScript's text item delimiters}
try
set theResult to text item 2 of aString
on error m number n
log {n, m}
set AppleScript's text item delimiters to oldTIDs
end try
set AppleScript's text item delimiters to oldTIDs
return theResult
end parse
on RepairAgain(remoteID, remoteMac)
try
delay 30
do shell script "ssh -l " & remoteID & " " & remoteMac & " diskutil
repairPermissions /"
on error
-- allow remote machine time to bring itself up again
display dialog "Unable to proactively RepairPremissions because unable
to ssh into " & remoteMac & ". It may be down still. Do you want to try
again?"
if button returned of the result = "OK" then
my RepairAgain(remoteID, remoteMac)
end if
end try
end RepairAgain
(* end script *)
--
Sander Tekelenburg, <
http://www.euronet.nl/~tekelenb/>
_______________________________________________
applescript-users mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/applescript-users
Do not post admin requests to the list. They will be ignored.