how to close an active document in Mac OS using shell script - macos

I am closing active document using apple script as below
tell application "Microsoft Word"
activate
try
if not (exists active document) then error number -128
close active document saving yes
on error
end try
end tell
want to do similar action using shell script. I want to gracefully close it and don't want to use kill command . And I don't want to use osascript to call an apple script . I want a graceful way using native shell commands

Hi you can use osascript in the shell code
#!/bin/sh
osascript <<EOF
tell application "$1"
close (every window whose name is "$2")
end tell
EOF
Compile this code and make filename.sh
or you can use
#!/bin/sh
osascript <<EOF
tell application "Preview"
close (every window whose name is "$1")
end tell
EOF
To use this from cmd type $./file_name Preview application name
Here I used the reference of https://ss64.com/osx/osascript.html

Related

iterm2 after upgrade does not open up profiles

I want to be able to type at command prompt
it2 myMachine and have a new session pop up with defaults for that profile in Iterm2.
The following used to work until upgrades, where $1 is the profile name...
osascript <<ENDSCRIPT
on run argv
tell application "iTerm"
activate
tell the first terminal
launch session "$1"
end tell
end tell
end run
ENDSCRIPT
71:79: syntax error: Expected class name but found identifier. (-2741)
I also am looking at straight osascript in bash. But new tab does not get command.
osascript -e "tell application \"Terminal\""
-e "tell application \"System Events\" to keystroke \"t\" using {command down}"
-e "do script \"cd $pwd; clear\" in front window"
-e "end tell"
I found all on iterm2 help pages... tell application "iTerm2" tell current window create tab with default profile end tell end tell There are many standard Applescript functions (e.g., to get the window's size and position) that are not documented here. create tab with default profile create tab with profile "name"

Access built-in Power Manager? states

Im trying to write a super simple applescript that will launch the OneDrive App, or ensure it is open, whenever the machine's power source is set to plugged in, and will quit, or make sure is closed, when the power source is set to battery.
I'm having trouble finding how to access the built-in "power indicator" in Yosemite. All of my searches lead to old, irrelevant results from years ago.
Edit: I think I will have to use a do shell script within the applescript using pmset -g batt
Now drawing from 'AC Power'
-InternalBattery-0 100%; charged; 0:00 remaining
And parse this result, but I am not sure how.
Edit: Here it is for anyone in the future who may want something similar:
global appName
on appIsRunning()
tell application "System Events" to (name of processes) contains appName
end appIsRunning
on acIsConnected()
return (do shell script "system_profiler SPPowerDataType | grep -q 'Connected: Yes' && echo \"true\" || echo \"false\"") as boolean
end acIsConnected
on toggleApp()
if my acIsConnected() then
if not my appIsRunning() then
tell application "Finder"
open application file (appName & ".app") of folder "Applications" of startup disk
end tell
end if
else
tell application appName
quit
end tell
end if
end toggleApp
-- This will only be executed once.
on run
set appName to "OneDrive"
end run
-- This will be executed periodically, specified in seconds, every return.
on idle
my toggleApp()
-- Execute every 2 minutes.
return 120
end idle
-- Not mandatory, but useful for cleaning up before quiting.
on quit
-- End handler with the following line.
continue quit
end quit
Here is a one-liner that polls for connected status, since I guess you can have less than 100% and still be connected (charging).
set acConnected to (do shell script "system_profiler SPPowerDataType |grep -q 'Connected: Yes' && echo \"true\" || echo \"false\"") as boolean
Here's another one liner...
set acConnected to last word of paragraph 1 of (do shell script "ioreg -w0 -l | grep ExternalChargeCapable")
If you are happy to use a third party tool, you can avoid polling for the battery state. This will make your script more efficient.
Power Manager can run AppleScripts when the battery state changes. How to Run a Command When Switching to Battery Power, walks through how to set this up for scripts.
Swap out the #!/bin/sh for #!/usr/bin/osascript in the script, and you can use AppleScript.
Disclaimer: I wrote Power Manager and can answer comments about how it works.
Provided you have battery icon on screen's top right:
tell application "System Events" to tell process "SystemUIServer" ¬
to value of attribute "AXDescription" of ¬
(first menu bar item whose value of attribute "AXDescription" ¬
begins with "Battery") of menu bar 1
You get "Battery: Charged" or "Battery: Calculating Time Remaining… " or something else

On osx, how to open new iterm terminal tab from one script then run command in that temrinal window

I am running osx. I have a script which runs the full stack then runs grunt at the end. I want to be able to separate running grunt in a separate terminal tab, i am using iterm.
I have tried something like
open -a Terminal "cd ~/dev/work/poc/user-interface/src/main/webapp; grunt"
any ideas?
This should do it for you (obviously change dir & command):
osascript -e '
tell app "iTerm"
activate
tell the first terminal
launch session "Default Session"
tell the last session
set name to "New Session"
write text "cd /usr/bin; ls"
end tell
end tell
end tell'
It's a slightly modified version of something I wrote to add iTerm support for RStudio.
Like this:
#!/bin/bash
osascript -e '
tell application "Terminal"
do script "date"
activate
end tell'
Replace date with whatever you want it to do.

OSX - How to auto Close Terminal window after the "exit" command executed.

When I'm done with Terminal, I want to exit it. Right now, I have three options:
killall Terminal. It will end the process, but rather abruptly. I don't think this is the best idea.
Call exit. I've changed the settings so exit closes Terminal. The app still appears open in the Dock though, and doesn't do what I want it to do.
Right click>Quit. However, this isn't a Terminal command to exit it.
So now, what is the way I should exit and close Terminal? I've heard something about osascript but I'm not too sure. I want to exit and close, so that Terminal is no longer open, both as a window and as a process.
in Terminal.app
Preferences > Profiles > (Select a Profile) > Shell.
on 'When the shell exits' chosen 'Close the window'
How about the good old Command-Q?
Actually, you should set a config on your Terminal, when your Terminal is up press ⌘+, then you will see below screen:
Then press shell tab and you will see below screen:
Now select Close if the shell exited cleanly for When the shell exits.
By the above config each time with exit command the Terminal will close but won't quit.
In the Terminal app, Preference >> Profiles tab.
Select the Shell tab on the right.
You can choose Never Ask before closing to suppress the warning.
You could use AppleScript through the osascript command:
osascript -e 'tell application "Terminal" to quit'
In a terminal window, you can type:
kill -9 $(ps -p $PPID -o ppid=)
This will kill the Terminal application process, which is the parent of the parent of the current process, as seen by the kill command.
To close a Terminal window from within a running script, you need to go up one more level in the process hierarchy like this:
kill -9 $(ps -p $(ps -p $PPID -o ppid=) -o ppid=)
I 've been using ctrl + d. It throws you out into the destination where You've started the sqlite3 command in the first place.
osascript -e "tell application \"System Events\" to keystroke \"w\" using command down"
This simulates a CMD + w keypress.
If you want Terminal to quit completely you can use:
osascript -e "tell application \"System Events\" to keystroke \"q\" using command down"
This doesn't give any errors and makes the Terminal stop cleanly.
You can also use this convoluted command, which does not trigger a warning about terminating its own process:
osascript -e "do shell script \"osascript -e \\\"tell application \\\\\\\"Terminal\\\\\\\" to quit\\\" &> /dev/null &\""; exit
This command is quite long, so you could define an alias (such as quit) in your bash profile:
alias quit='osascript -e "do shell script \"osascript -e \\\"tell application \\\\\\\"Terminal\\\\\\\" to quit\\\" &> /dev/null &\""; exit'
This would allow you to simply type quit into terminal without having to fiddle with any other settings.
Use the osascript command in your code as icktoofay mentioned: osascript -e 'tell application "Terminal" to quit'
Then, open Terminal preferences, go to Settings > Shell, and set "Prompt before closing:" to "Never." Terminal should now quit completely (not remain open in your dock) and ignore the prompt before quitting. If you have only one Terminal window open and the osascript command is your last line of code, it should wait for whatever command you ran before to finish.
This would not be ideal if you are running scripts in the same window or other windows in the background (for instance, you may run a command in the background and continue using the current window for other commands if the first command is followed by an ampersand); be careful!
If you wrap the osascript code in a shell script file, you can probably call it with whatever pithy file-name you give it---as long as it is in Terminal's search path (run echo $PATH to see where Terminal looks for scripts).
I've been using
quit -n terminal
at the end of my scripts. You have to have the terminal set to never prompt in preferences
So Terminal > Preferences > Settings > Shell
When the shell exits
Close the window
Prompt before closing
Never
Create a script:
cat ~/exit.scpt
like this:
Note: If there is only one window, just quit the application, else simulate command + w to close the tab)
tell application "Terminal"
set WindowNum to get window count
if WindowNum = 1 then
quit
else
tell application "System Events" to keystroke "w" using command down
end if
end tell
Then add a alias in your *shrc
just like vi ~/.bashrc or zshrc (anything else?)
add it:
alias exit="osascript ~/exit.scpt"
And source the ~/.bashrc or reopen your terminal.app
This is what I did for a command I just wrote. I wanted to be able to create a "shortcut" to the Backup directory for Apple Configurator that worked on different computers, but since it's relative to the user's home directory, I needed to make it a .command file. Here are the contents:
#!/usr/bin/env bash
open "${HOME}/Library/Application Support/MobileSync/Backup"
(sleep 0.1 ; osascript -e 'tell application "Terminal" to quit') &
I tried several variations of the answers here. No matter what I try, I can always find a use case where the user is prompted to close Terminal.
Since my script is a simple (drutil -drive 2 tray open -- to open a specific DVD drive), the user does not need to see the Terminal window while the script runs.
My solution was to turn the script into an app, which runs the script without displaying a Terminal window. The added benefit is that any terminal windows that are already open stay open, and if none are open, then Terminal doesn't stay resident after the script ends. It doesn't seem to launch Terminal at all to run the bash script.
I followed these instructions to turn my script into an app: https://superuser.com/a/1354541/162011
If this is a Mac you type 'exit' then press return.

Sending commands and strings to Terminal.app with Applescript

I want to do something like this:
tell application "Terminal"
activate
do script "ssh user#server.com"
-- // 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.
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
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.
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
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
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 ...
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
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.
Kinda related, you might want to look at Shuttle (http://fitztrev.github.io/shuttle/), it's a SSH shortcut menu for OSX.
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
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 jdoe#example.com '/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.
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!
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.
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
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.
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.

Resources