Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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.

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

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) : execute ps to print when process identifed by variable $$ started ($$ expands to the PID ot this bash session). Then filter out the header (which contains the word STARTED). Assign resulting value to variable shell_started.

ps -A -o pid -o command | grep '/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal -psn' | grep -v grep | cut -d '/' -f 1 : execute ps to print all process command names, select the one that matches the full path to Terminal, filter out any spurious grep processes and extract process ID with cut.

terminal_started=$(ps -A -o lstart $(...) | grep -v STARTED) : execute ps to print when process Terminal started, and filter out the header (which contains the word STARTED).

(I had to create terminal_started in two steps to get rid of TABs ps 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.

share|improve this answer
    
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
1  
Thanks, could you 1) Post output of command ps -A -o pid -o command | grep Terminal and 2) Try the code in the answer modifying terminal_started to terminal_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 the head -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
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.