I'm curious if anyone has found a good way to have the Terminal app on a Mac open without opening a window. The startup preference has the options "New window with settings:" or open a specific window group, but I would prefer it just open nothing to begin with. I've tried saving a window group with no windows in it, but it reverts to just opening a default window again.
I couldn't find any option to prevent a window from opening when Terminal is started, but you could check whether the current bash
session was started at exactly the same time Terminal was started. If that's the case, the bash
session should exit.
You will see a window appearing and disappearing for a fraction of a second, though.
Add the following code (tested on Mac OS X 10.5.8 (Leopard) [see my note below] and OS X 10.8.2 (Mountain Lion)) to the beginning of your ~/.bash_profile
:
shell_started=$(ps -A -o lstart $$ | grep -v STARTED)
terminal_started=$(ps -A -o lstart $(ps -A -o pid -o command | grep '/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal -psn' | grep -v grep | cut -d '/' -f 1) | grep -v STARTED)
if [ "X$shell_started" == "X$terminal_started" ]; then exit; fi
Code explanation:
shell_started=$(ps -A -o lstart $$ | grep -v STARTED
) : executeps
to print when process identifed by variable$$
started ($$
expands to the PID ot thisbash
session). Then filter out the header (which contains the wordSTARTED
). Assign resulting value to variableshell_started
.
ps -A -o pid -o command | grep '/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal -psn' | grep -v grep | cut -d '/' -f 1
: executeps
to print all process command names, select the one that matches the full path to Terminal, filter out any spuriousgrep
processes and extract process ID withcut
.
terminal_started=$(ps -A -o lstart $(...) | grep -v STARTED)
: executeps
to print when process Terminal started, and filter out the header (which contains the wordSTARTED
).(I had to create
terminal_started
in two steps to get rid of TABsps
added to the output.)
if [ "X$shell_started" == "X$terminal_started" ]; then exit; fi
: Compare both dates and if equal, exit the shell, that is, close the Terminal window.
If it is not working for you (as it was the case for the OP, who uses Mac OS X 10.6.8 (Snow Leopard)), try:
shell_started=$(ps -A -o lstart $$ | grep -v STARTED)
terminal_started=$(ps -A -o lstart $(ps -A -o pid -o command | grep '/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal -psn' | grep -v grep | tail -n 1| cut -d '/' -f 1) | grep -v STARTED)
if [ "X$shell_started" == "X$terminal_started" ]; then exit; fi
(The only difference here is a tail
in terminal_started
which selects the last entry printed by ps
, in case there's more than one.)
Note for Mac OS X 10.5.8 (Leopard):
On my old PowerBook G4 I noticed that sometimes there was a one sec difference between the starting times of Terminal and the current bash
session. If you are running into similar problems with a slow computer, add these three lines lines to the end of the code above:
one_second_before=$(expr "$shell_started" : '.*:\([0-9][0-9]\) .*' - 1)
shell_started_one_second_before=$(echo $shell_started | sed 's/\(.*:\)\([0-9][0-9]\)\( .*\)/\1'$one_second_before'\3/')
if [ "X$shell_started_one_second_before" == "X$terminal_started" ]; then exit; fi
There's a boundary condition this code doesn't handle well, namely, when the shell was started in second 0, but I didn't want to add further complexity.
-
Interesting, I like the idea, but it doesn't seem to be working for me. shell_started is Tue Jan 29 02:52:04 2013 but terminal_started is Tue Jan 29 02:52:04 2013 Tue Jan 29 02:52:04 2013 Tue Jan 29 02:52:04 2013 Tue Jan 29 02:52:04 2013 etc... It seems there are too many entries being found by terminal_started? – Thursdays Coming Jan 29 '13 at 9:52
-
I tested it with Mountain Lion (10.8), which OS X version is your Mac running? Could you add this to your
~/.bash_profile
, close Terminal, open it and paste the output?terminal_pid=$(ps -A -o pid -o command | grep Terminal | grep -v grep | cut -d '/' -f 1); echo "Terminal PID is $terminal_pid"; echo "Terminal started at $(ps -A -o lstart $terminal_pid | grep -v STARTED)"; echo "Terminal PID with BSD syntax is $(ps aux | grep Terminal | grep -v grep | awk '{print $2}')"
– jaume Jan 29 '13 at 10:29 -
Output: Terminal PID is 551 29726 Terminal started at Sun Jan 27 16:19:22 2013 Sun Jan 27 16:19:27 2013 Sun Jan 27 16:19:27 2013 ... etc Many more of these. Thu Jan 31 22:45:20 2013 Thu Jan 31 22:45:20 2013 Terminal PID with BSD syntax is 29726 551. Also, I am running 10.6.8 – Thursdays Coming Feb 1 '13 at 5:46
-
1Thanks, could you 1) Post output of command
ps -A -o pid -o command | grep Terminal
and 2) Try the code in the answer modifyingterminal_started
toterminal_started=$(ps -A -o lstart $(ps -A -o pid -o command | grep Terminal | grep -v grep | head -n 1 | cut -d '/' -f 1) | grep -v STARTED)
(notice thehead -n 1
) and report back? – jaume Feb 1 '13 at 6:27 -
Cool, I read up a little on this and was able to use tail instead of head in your modified terminal_started line to grab the last entry. This seems to have worked just as you said. Thanks! – Thursdays Coming Feb 3 '13 at 5:00