Quit an applescript application after the execution of a shell script - shell

I was wondering if it is possible for an applescript application to run a shell script, then quit before the execution of the shell script is completed. This would be useful when running a server for a given amount of time. Instead of needing the applescript to be constantly running in the background, is there any way to run a function independently?
set server_name to text returned of (display dialog "Choose server." default answer "")
set success to do shell script "if [ -f \"/Users/jessefrohlich/Documents/Minecraft/" & server_name & "/minecraft_server.jar\" ]; then
echo 1;
else
echo 0;
fi"
if success is equal to "1" then
do shell script "cd /Users/jessefrohlich/Documents/Minecraft/" & server_name & "
java -Xmx1024M -Xms1024M -jar minecraft_server.jar"
else
display dialog "Sorry, the file you chose is invalid."
end if
When the above is run as an application, it will launch the server properly. However, the application runScript.app will continue to run. The server will keep running even if the applescript is force quit. Is there any way to have it quit automatically, as soon as the server is launched?
Thanks

Try this. Good luck.
-- "> /dev/null" redirects standout out to nowhere land
-- - you can use some other file path if you want to capture its output
-- "2>&1" redirects standard error to the same place as standard out
-- - 2 stands for standard error
-- - 1 stands for standard out
-- - > is the redirect symbol
-- - & changes redirect's output from a file to a file descriptor (in this case standard out)
-- & the trailing & sends the process to the background
do shell script "cd /Users/jessefrohlich/Documents/Minecraft/" & server_name & " java -Xmx1024M -Xms1024M -jar minecraft_server.jar > /dev/null 2>&1 &"

You can add a condition to your Applescript to have it "ignore application responses", and it will then go on to whatever else is in your applescript, including quitting it.
The Apple Site has details: https://developer.apple.com/library/mac/#documentation/applescript/conceptual/applescriptlangguide/reference/ASLR_control_statements.html

Related

Tell an AppleScript to Restart Itself

I have an AppleScript saved as an application. When first run, it asks the user if they want to move it to the Applications folder. What I would like to be able to do is, after it's been moved, have the script quit itself and then reopen.
Obviously I can't say
tell me to quit
tell me to activate
...because it would stop running after the quit command.
Any suggestions?
Just run the script from inside the script, and make sure to terminate the current running of it with a return (can skip the actual return command if it's the last line of the script
-- do stuff
display dialog "Here I am again"
-- set alias to the script
-- run the script
set myScript to path to me
run script myScript
-- end current iteration
return
You can break out of this script by canceling the dialog, but you'll probably want to set a condition to check whether to run the script again.
Here's how I'd do this. Basically, You check if the application is running from the Applications folder. If it isn't, move it there, open another instance, and quit. Seems to work flawlessly. The activate in the beginning is because it seems that the application doesn't always move itself to the foreground:
--incase the application doesn't do this automagically
activate
set my_path to POSIX path of (path to me)
if my_path does not start with "/Applications/" then
set new_path to "/Applications/" & quoted form of (my name & ".app")
--"mv" wont move the application into the new location if it exists
try
do shell script "rm -rf " & new_path
end try
do shell script "mv -f " & quoted form of my_path & " " & new_path
do shell script "open -n " & new_path & " &> /dev/null &"
quit
end if
What I am doing.
First I enabled at by running the following command in Terminal (this only has to be done once)
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist
then I have the following script
display dialog "running"
set mypath to POSIX path of (path to me)
set lun to open for access POSIX file "/tmp/springboard" with write permission
write "open " & mypath & linefeed to lun
close access lun
do shell script "at -f /tmp/springboard +1 minute"
quit

Applescript Execute Shell with Input and Admin Privileges

I'm trying to write an automator service to fire up virtualhost.sh in a terminal.
Using the Services context menu the dialog opens to ask for the name of virtual host, then runs an applescript to launch terminal and pass in the input text.
What I want is to pass in my username and password to admin privileges so that I don't need to pass it in the terminal with sudo.
This can be done with do shell script but that executes a bin/sh and the virtualhost.sh is a bash script so I get the error bin/sh: virtualhost.sh command not found
Alternately I can use do script with command but this doesn't allow me to pass in the user name and password.
My code looks like so:
on run {input, parameters}
set vhost to "virtualhost.sh " & input
tell application "Terminal"
activate
do shell script vhost user name "user" password "pass" with
administrator privileges
end tell
end run
This produces the bin/sh error previously mentioned.
With do script with command
on run {input, parameters}
set vhost to "virtualhost.sh " & input
tell application "Terminal"
activate
do script with command vhost user name "user" password "pass" with
administrator privileges
end tell
end run
This produces an escaping error: Expected end of line, etc. but found property.
Is there a way to do this correctly?
Not specifically familiar with AppleScript Studio, but you can do it in plain old AppleScript (which appears to have the same issue) if you provide a full path to virtualhost.sh. (Also, Terminal is not required with "do shell script".) Example:
set vhost to "/usr/local/bin/virtualhost.sh " & input
do shell script vhost user name "user" password "pass" ¬
with administrator privileges
You can also extend $PATH (which is by default /usr/bin:/bin:/usr/sbin:/sbin with "do shell script") to include the path to virtualhost.sh, e.g.:
set vhost to "{ PATH=$PATH:/usr/local/bin; virtualhost.sh " & input & "; }"
do shell script vhost user name "user" password "pass" ¬
with administrator privileges
If you want a relative path, you can put virtualhost.sh inside the script application or bundle (e.g. in Contents/Resources), either in Terminal or by control-clicking and choosing "Show Package Contents". Then use "path to me":
set vhostPath to "'" & POSIX path of (path to me) & ¬
"/Contents/Resources/virtualhost.sh" & "'"
set vhost to vhostPath & space & input
do shell script vhost user name "user" password "pass" ¬
with administrator privileges
Per the comment on my other answer, I'm posting a secondary answer more in the spirit of that there's a will, there's a way, but it's a different, more dangerous approach. However, it's the only solution I can think of to this particular requirement (to get the interactivity of Terminal, but without having to prompt for an administrator password while running a script as administrator).
This solution runs Terminal as root, which is what do shell script "command" with administrator privileges does. This is dangerous because you have an open Terminal window with root access, so carefully weigh benefits against potential consequences of, say, opening a new Terminal window and being at the Bash prompt as root.
For this reason, the Terminal instance that is opened is killed upon completion of the script; if the "kill" command is removed, be aware you'll get multiple instances of Terminal, rather than multiple windows within the same instance.
No idea if this works in AppleScript Studio (it works in AppleScript Editor), but I can't think of any reason why it wouldn't.
set input to "some_input"
set vhost to "/usr/local/bin/virtualhost.sh " & input
set kill to ¬
"terminal_pid=$(</tmp/terminal_pid); rm /tmp/terminal_pid; kill $terminal_pid"
-- launch Terminal as root, and save its process ID in /tmp/terminal_pid
tell application "Finder" to set beforeProcesses to processes
do shell script ¬
"/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal " & ¬
"&> /dev/null & echo $! > /tmp/terminal_pid" user name "user" password ¬
"pass" with administrator privileges
-- wait until the new Terminal is confirmed to be running
tell application "Finder"
repeat while (processes is equal to beforeProcesses)
do shell script "sleep 0.5"
end repeat
end tell
-- Perform script in root Terminal window that we just opened,
-- and kill Terminal when done to prevent open root prompt
-- and multiple processes.
tell application "Terminal"
activate
do script vhost & "; " & kill
end tell
-- optional: wait until Terminal is gone before continuing
do shell script "while [[ ( -f /tmp/terminal_pid ) " & ¬
"&& ( \"$(ps -p $(</tmp/terminal_pid) -o%cpu='')\" ) ]]; do sleep 0.5; done"

Applescript to ping test each client prior to ssh connection

I'm trying to make an Applescript that connects to a list local ssh machines, with each connection opening in a new terminal window. Prior to attempting the ssh connection, I'd like to ping the client to see if it's available: if it is, run the ssh command, if not then iterates to the next client. When I run the script it seems to work for the first connection but then gives me --> error number -10004 for the remaining clients (and hangs the debugger). Any feedback would be greatly appreciated, thanks!
set hosts to {"10.2.0.199", "10.2.0.11", "10.2.0.91", "10.2.1.591", "10.2.0.41"}
set uname to {"asus_client01", "asrock_comp", "msi003", "gigabyte4", "intel05client"}
tell application "Terminal"
activate
repeat with i from 1 to the count of hosts
set this_uname to item i of uname --extract individual username
set this_host to item i of hosts as string --extract iPv4
set uname_host to this_uname & "#" & this_host
set hostUp to true
try
do shell script "ping -c 1 -t 5 " & this_host
on error
set hostUp to false
display dialog this_host & " seems to be down."
delay 2
end try
if hostUp then
do shell script "ssh " & uname_host
end if
end repeat
end tell
There is a difference between do shell script and do script. The difference is that do shell script is part of the standard script addition and will open an non-interactive shell, execute the given string, and return stdout back to you without any help from another application like Terminal. do shell script should never been used in any other tell application block except itself (me) because you violate some AppleScript securities you can find in AppleScript release and technical notes. do script command is part of AppleScript command in the application Terminal. do script will enter the given string in the targeted window and execute that like you have typed in Terminal yourself. do script is only supported by Terminal application and can't be used outside of it.
So it's either do shell script:
do shell script "ping -o stackoverflow.com
or do script by using the Terminal
tell application "Terminal"
do script "ping -o stackoverflow.com"
end tell
So the total script could look something like this:
set hosts to {"10.2.0.199", "10.2.0.11", "10.2.0.91", "10.2.1.591", "10.2.0.41"}
set uname to {"asus_client01", "asrock_comp", "msi003", "gigabyte4", "intel05client"}
--security check: hosts list can't be longer than uname
if (count of hosts) > (count of uname) then return
repeat with i from 1 to count hosts
repeat 1 times -- simulate continue
set currentAddress to item i of hosts
set currentHostname to item i of uname
if not ((do shell script "ping -o -t 5 " & currentAddress & "&>dev/null && echo yes || echo no") as boolean) then
exit repeat -- continue
end if
tell application "Terminal"
do script "ssh " & currentHostname
end tell
end repeat
end repeat

Command Line & and &&

so currently what I am attempting to do is, remote onto a different server, launch a scheduled task, exit, change to a specified folder on my desktop, write a file
My code currently looks as such
C:MyOriginalFolder> psexec \\MYREMOTESERVER -u MYUSERNAME cmd
C:MYREMOTESERVER> SCHTASK.......
C:MYREMOTESERVER> exit & cd C:\\Users\ce132d & echo "Logged off" > MyLog.txt
//expected: the folder C:\\Users\ce132d should have a text file called MyLog.txt
//what happens: I end up in C:MyOriginalFolder with no MyLog.txt file created
When I remove the &'s and test it command by command, all is dandy and the expected behavior happens. But when linking them together with & and &&, the expected behavior does not happen.
So my question is this: is there some way of one-lining the actions of exiting, changing directory, and writing a text file?
I am eventually going to check if loging into the remote server was successful or not, and want to put those 3 actions into a if (successful login) {do 3 tasks} else {write error log}..
You send your remote server exit & cd C:\\Users\ce132d & echo "Logged off" > MyLog.txt.
Why do you expect that the cd ... should have any effect on your local directory?
When you send the commands line by line then your exit will EXIT the remote server context, then you are again on your local machine, therefore the rest of the commands works as expected.
The > MyLog.txt is being evaluated before any of the commands are run, including the cd. You can use > C:\Users\ce132d\MyLog.txt instead.
You can also use >> instead of > to append to a file.

How do you open a terminal with a specific path already cd'ed to?

How do I use the terminal to open another terminal window but with a path I specify?
I am using automator to load my work stuff when I get to work, but I need to know how to do this:
Open Terminal and Type:
• cd Work/Company/Project/
• script/server
And then new tab in that terminal window and cd to the same folder.
This opens a new terminal window from a command prompt on Mac OSX , executes "cd /" and then keeps the window on top:
osascript -e 'tell application "terminal"' -e 'do script "cd /"' -e 'end tell'
You can put this into a script like this:
#!/bin/sh
osascript -e 'tell application "terminal"' -e "do script \"cd $1\"" -e 'end tell'
Hope this helps.
Use an applescript to do this.
e.g. Open Terminal Here
You can write a shell script to cd to that directory
So write a script that executes something like cd /user/music or something like that, save it as myscript.sh and run it using chmod +x myscript.sh.
This resource from the OS X developer network is pretty helpful
The two scripts below together handle the common scenarios:
1) If Terminal is already running, open a new terminal window and run the 'cd mydir' there
2) If terminal is not already running, use the initial window that Terminal spawns (window 0), rather than annoyingly launching a second window
NOTE: what's not quite perfect is if Terminal has several windows open, all of them will be brought to the front, overlapping any other apps. A solution to raising only the last terminal window to the front appears to require the black magic of AppleScriptObjC - references below:
https://apple.stackexchange.com/questions/39204/script-to-raise-a-single-window-to-the-front
http://tom.scogland.com/blog/2013/06/08/mac-raise-window-by-title/
Script 1 - open a text editor and save as:
/usr/local/bin/terminal-here.sh
#!/bin/sh
osascript `dirname $0`/terminal-here.scpt $1 > /dev/null 2> /dev/null
Script 2 - open 'AppleScript Editor', paste contents below and save as:
/usr/local/bin/terminal-here.scpt
# AppleScript to cd (change directory) to a path passed as an argument
# If Terminal.app is running, the script will open a new window and cd to the path
# If Terminal.app is NOT running, we'll use the window that Terminal opens automatically on launch
# Run script with passed arguments (if any)
on run argv
if (count of argv) > 0 then
# There was an argument passed so consider it to be the path
set mypath to item 1 of argv
else
# Since no argument was passed, default to the home directory
set mypath to "~"
end if
tell application "System Events"
if (count (processes whose bundle identifier is "com.apple.Terminal")) is 0 then
# Terminal isn't running so we'll make sure to run the 'cd' in Terminal's first window (0)
tell application "/Applications/Utilities/Terminal.app"
# Turn off echo, run the 'cd', clear screen, empty the scrollback, re-enable echo
do script "stty -echo; cd " & (mypath as text) & ";clear; printf \"\\e[3J\"; stty echo" in window 0
activate last window
end tell
else
# Terminal is already running so we'll let it open a new window for our 'cd' command
tell application "/Applications/Utilities/Terminal.app"
# Turn off echo, run the 'cd', clear screen, empty the scrollback, re-enable echo
do script "stty -echo; cd " & (mypath as text) & ";clear; printf \"\\e[3J\"; stty echo"
activate last window
end tell
end if
end tell
end run

Resources