OSX bash minimize window - bash

In the Mac and using the bash shell, I want to execute a file that contains a single command (to start Jupyter Lab) and immediately minimize the terminal window.
Is there a way to do this WITHOUT installing third party software?

Yes, just use osascript and Applescript:
osascript -e 'tell application "Terminal" to set visible of front window to false'

Building on Paul R's answer, which in my testing appears to make the window fully hidden and unrecoverable, you can use the following to minimise the window to the dock if access is required again later:
osascript -e 'tell application "Terminal" to set miniaturized of every window to true'

You can create a file that with the command extension, for example jupiter-lab.command.
You add execution rights on it (chmod +x jupiter-lab.command). You edit the file and insert commands like in a bash script.
For example to open App Store, you could insert :
open "/Application/App Store.app"
The first time you double click on it, you will get a popup that tells you that the command has ended quickly. Just check the Suppress this message permanently not to see it anymore.
Note : the terminal will not be minimised but will be closed.

Related

How to avoid a zombie window when running MacOS shel/Applescript script

I routinely open a lot of Terminal windows each with an ssh session. To streamline the process I have a series of shell scripts that look like this:
#!/bin/sh
osascript <<EOS
tell application "Terminal"
activate
do script "set_background_color salmon; ssh alan#demo.znyx.com"
end tell
EOS
This works. I can either execute the script from a shell prompt or click it in the Finder window. (To do this the file name suffix is .command instead of .sh)
The problem is that when I execute it from Finder, I end up with a dead window ("Process Completed") behind the window I intended to open. Is there any way to get rid of it or not have it open in the first place?
UPDATE:
The solution in this other question results in dialog boxes appearing that provide confirm/review/cancel options. This is undesirable.
When you double-click a .command file, the file is passed to Terminal and Terminal creates a window and executes the commands within it. The commands in your .command file use AppleScript to tell Terminal to run a command in yet another window.
Why not remove the middle man and just put the ultimate commands you want to run — set_background_color salmon; ssh alan#demo.znyx.com — in the .command file? Drop that stuff with running an AppleScript. In other words, the contents of your .command file should just be:
set_background_color salmon
ssh alan#demo.znyx.com
Alternatively, you could take the AppleScript from your .command file (the part between <<EOS and EOS), put it into Script Editor.app, and save it as an applet.

How to execute a shell script from within an .app, and show it in the Terminal?

My goal is to execute a shell script by double clicking on an OS X .app, and the Terminal to be visible to the user (my script has a CLI GUI).
Any ideas? I've tried appify but I can't get it to show the Terminal window.
Many thanks.
For those interested, I found the following solution which involves using an Apple Script command.
First you need to create a launcher.sh script.
Use the code below. The many quotes below allow your app to run from a path with spaces.
#!/bin/bash
scriptPath=$(dirname "$0")'/yourscript.sh'
osascript -e 'tell app "Terminal" to do script "\"'"$scriptPath"'\""'
Use appify to generate an app bundle.
Type this in the Terminal to do it:
appify launcher.sh "Your app name"
From Finder,
right-click on your generated app bundle, Show package contents, and paste yourscript.sh into /Contents/MacOS/

Programmatically add application icon to dock on install

I would like my application to be automatically added to the dock after the package (DMG) is installed?
Does anyone know how to do this?
There's a couple ways to do this, Andrew, and a lot of this depends on how you're doing your application installing.
If you are using PackageMaker to install your app, you can run a "postflight" script which adds your app's icon to the "defaults" (i.e. the preferences) of the dock. This older MacRumors thread shows how to do that.
If you are not using PackageMaker, then you might have to run an Applescript from within your app that does the same "defaults" writing trick. Here's a thread on AskDifferent that shows how.
In both cases you need to kill the dock (or Finder?) and restart it in order to get the change to pick up and show.
I would suggest you run the following AppleScript code, replacing myapp with the app you want to add to de dock, including its path.
In the example below, I am adding the system app "System Preferences", but you can do the same with your own path, just assign the path of your app to the myapp variable.
on run
set myapp to "/Applications/System Preferences.app"
try
tell application "Dock" to quit
end try
do shell script "defaults write com.apple.dock persistent-apps -array-add '<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>" & myapp & "</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>'"
try
tell application "Dock" to activate
end try
end run
This follows the suggestion given by Michael, but it should be more gentle as it just quits the Dock rather thank killing it.
If you prefer bash, you could run the following code, again assigning the path of your own app to the myapp variable.
Note: in the bash case, you have to use double slashes when specifying your the path, as you can see in the example.
#!/bin/bash
myapp="//Applications//System Preferences.app"
defaults write com.apple.dock persistent-apps -array-add "<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>$myapp</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>"
osascript -e 'tell application "Dock" to quit'
osascript -e 'tell application "Dock" to activate'

Close Terminal window from within shell script (Unix)?

Is there a way to close a Terminal window from within a shell script? I have a .command file that should just get out of the way once it's done.
Using exit 0 will cleanly terminate the script.
Whether Terminal window stays open is user-configurable. The default is to always stay open. To change this:
Terminal.app > Preferences > Profiles > Shell
- "When the shell exists:"
> Close if the shell exited cleanly
- "Ask before closing:"
(•) Never
-- OR --
(•) Only if there are....
When "Close if shell exited cleanly" is used, the script will close the window if the exit result is 0, which is the default if nothing went wrong.
Since you don't want to delete all Terminal windows, first change the name of your window from "Terminal" to something else:
echo -n -e "\033]0;My Window Name\007"
Then at the end of the script, use:
osascript -e 'tell application "Terminal" to close (every window whose name contains "My Window Name")' &
You can use apple script to quit the terminal app. Add the following to your script -
osascript -e 'tell application "Terminal" to quit'
This will give you a popup confirming to close the app. You can disable this in Terminal preferences.
Alternatively, you can also use killall command to quit the app. The following would work just as well.
killall Terminal
Note:
Just as a side note, you can freely add the above commands to your script and it would work as you want. However, there are few caveats. First being you will limit the ability of your script to work on different boxes. Secondly, it would be safer to use nohup so that any commands that are currently running won't quit due to quitting of the Terminal app.
This works for me:
#!/bin/sh
{your script here}
osascript -e 'tell application "Terminal" to close (every window whose name contains ".command")' &
exit
This will work for closing just your windows opened with a .command file but leave things already running in other terminal windows. I know that I almost always have either sass or grunt watch something so I don't want to quit terminal totally.
closeWindow() {
/usr/bin/osascript << _OSACLOSE_
tell application "Terminal"
close (every window whose name contains "YourScriptName")
end tell
delay 0.3
tell application "System Events" to click UI element "Close" of sheet 1 of window 1 of application process "Terminal"
_OSACLOSE_
}
This will close the Terminal window for your script and keep any other Terminal windows open as long as their window titles don't match. For it to work Terminal will have to be added to the list of applications permitted to use the Accessibility framework. You can also cycle through Terminal windows with a repeat command and close every window x that contains a UI element "Close" on sheet 1.
I find the best solution for this is to use Automator to create a true OSX application which will work the same way regardless of how your system is configured. You can have the Automator run your shell script, or you can embed the shell script itself in Automator.
Here is how you do it:
Run Automator (in Applications).
Choose "New Document" and when it
asks "Choose a type for your document" choose "Application"
In the
left panel, select "Utilities" then "Run Shell Script".
Type in your
script commands in the workflow item in the right panel. You can either call another
shell script, or just put your commands in their directly.
Save the
Application, which will be a full-fledged Mac App. You can even
cut-and-paste icons from other apps to give your script some
personality.
#!/bin/bash -x
{your script here}
. exit 0
kill -9 $PPID
you can also create a shortcut for your script:
cp yourscript.sh ~/bin/yourshortcutnamewhateveryouwant
then type
yourshortcutnamewhateveryouwant
will run whatever is writen into script at any directory.

Executing Shell Scripts from the OS X Dock?

How do I set up a shell script to execute from the Mac OSX dock? It seems that simply creating a shortcut will open the file in my editor. Is there a flag I need to set somewhere to tell it to run instead of opening it for editing?
You could create a Automator workflow with a single step - "Run Shell Script"
Then File > Save As, and change the File Format to "Application". When you open the application, it will run the Shell Script step, executing the command, exiting after it completes.
The benefit to this is it's really simple to do, and you can very easily get user input (say, selecting a bunch of files), then pass it to the input of the shell script (either to stdin, or as arguments).
(Automator is in your /Applications folder!)
If you don't need a Terminal window, you can make any executable file an Application just by creating a shell script Example and moving it to the filename Example.app/Contents/MacOS/Example. You can place this new application in your dock like any other, and execute it with a click.
NOTE: the name of the app must exactly match the script name. So the top level directory has to be Example.app and the script in the Contents/MacOS subdirectory must be named Example, and the script must be executable.
If you do need to have the terminal window displayed, I don't have a simple solution. You could probably do something with Applescript, but that's not very clean.
On OSX Mavericks:
Create your shell script.
Make your shell script executable:
chmod +x your-shell-script.sh
Rename your script to have a .app suffix:
mv your-shell-script.sh your-shell-script.app
Drag the script to the OSX dock.
Rename your script back to a .sh suffix:
mv your-shell-script.app your-shell-script.sh
Right-click the file in Finder, and click the "Get Info" option.
At the bottom of the window, set the shell script to open with the terminal.
Now when you click on the script in the dock, A terminal window will pop up and execute your script.
Bonus: To get the terminal to close when your script has completed, add exit 0 to the end and change the terminal settings to "close the shell if exited cleanly" like it says to do in this SO answer.
I know this is old but in case it is helpful to others:
If you need to run a script and want the terminal to pop up so you can see the results you can do like Abyss Knight said and change the extension to .command. If you double click on it it will open a terminal window and run.
I however needed this to run from automator or appleScript. So to get this to open a new terminal the command I ran from "run shell script" was "open myShellScript.command" and it opened in a new terminal.
As long as your script is executable and doesn't have any extension you can drag it as-is to the right side (Document side) of the Dock and it will run in a terminal window when clicked instead of opening an editor.
If you want to have an extension (like foo.sh), you can go to the file info window in Finder and change the default application for that particular script from whatever it is (TextEdit, TextMate, whatever default is set on your computer for .sh files) to Terminal. It will then just execute instead of opening in a text editor. Again, you will have to drag it to the right side of the Dock.
In the Script Editor:
do shell script "/full/path/to/your/script -with 'all desired args'"
Save as an application bundle.
As long as all you want to do is get the effect of the script, this will work fine. You won't see STDOUT or STDERR.
I think this thread may be helpful: http://forums.macosxhints.com/archive/index.php/t-70973.html
To paraphrase, you can rename it with the .command extension or create an AppleScript to run the shell.
As joe mentioned, creating the shell script and then creating an applescript script to call the shell script, will accomplish this, and is quite handy.
Shell Script
Create your shell script in your favorite text editor, for example:
mono "/Volumes/Media/~Users/me/Software/keepass/keepass.exe"
(this runs the w32 executable, using the mono framework)
Save shell script, for my example "StartKeepass.sh"
Apple Script
Open AppleScript Editor, and call the shell script
do shell script "sh /Volumes/Media/~Users/me/Software/StartKeepass.sh" user name "<enter username here>" password "<Enter password here>" with administrator privileges
do shell script - applescript command to call external shell commands
"sh ...." - this is your shell script (full path) created in step one (you can also run direct commands, I could omit the shell script and just run my mono command here)
user name - declares to applescript you want to run the command as a specific user
"<enter username here> - replace with your username (keeping quotes) ex "josh"
password - declares to applescript your password
"<enter password here>" - replace with your password (keeping quotes) ex "mypass"
with administrative privileges - declares you want to run as an admin
Create Your .APP
save your applescript as filename.scpt, in my case RunKeepass.scpt
save as... your applescript and change the file format to application, resulting in RunKeepass.app in my case
Copy your app file to your apps folder
Exact steps to achieve that in macOS Monterey 12.3
Open Automator
File -> New
Choose Application
Go to Library -> Utilities
Double-click Run Shell Script
Type in whatever command you want to run. For example, try the command to toggle Dark Mode:
osascript -e 'tell app "System Events" to tell appearance preferences to set dark mode to not dark mode'
File -> Save
Drag the saved file to the Dock, done!
pip install mac-appify
I had trouble with the accepted solution but this command worked for me.
Install
pip install mac-appify
Run
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/appify ~/bin/webex_start.sh ~/Desktop/webex.app
Adding to Cahan's clear answer ... to open a shell script from the dock without passing any arguments to it, try:
open [name of your script].scpt"
example:
open "//Users/user/Library/Mobile Documents/com~apple~ScriptEditor2/Documents/myScript.scpt"
Someone wrote...
I just set all files that end in ".sh" to open with Terminal. It works
fine and you don't have to change the name of each shell script you
want to run.

Resources