22

Sometimes I inadvertently exit from a Terminal session (usually because I think I'm connected to a remote system, when I'm not), so I get to this point:

enter image description here

How I can I restart the session at this point ? I don't want to close the window or tab because I have a bunch of tabs all set up for my normal workflow, so I just want to get the session in the current tab going again (i.e. get back to a bash prompt).

The only solution I've found so far is to quit Terminal completely and open it again, but that is far from ideal as it obviously interrupts anything else I'm doing in other Terminal windows/tabs.

  • 1
    Linux (KDE/Gnome) terminal emulators let you re-order tabs. So if you start a new tab, you can move it over to replace the one you closed. Doesn't OS X's terminal have that? (I'm not a mac person, I just saw this in "hot network questions".) I also like to use GNU screen to multiplex a lot of shell sessions, rather than tabs in a terminal window. I have another tab with a screen session on another computer. I sometimes open another terminal if I want to see two things at once, but normally I like having my shells numbered, the way screen does, rather than just there – Peter Cordes Dec 17 '15 at 22:28
  • 1
    Anyway, I'd suggest screen (or tmux if you don't already know screen) for keeping multiple shells on the same host in one GUI tab. This two-level hierarchy of tabs / screen-windows allows having lots of stuff open, without losing track of what's where. Also, like I said, having numbers for the different shells makes it easy to remember which number to swap to (^t 8 for example) for a given context, instead of visually counting which tab to click or (or how many ctrl-pgup to hit). – Peter Cordes Dec 17 '15 at 22:31
  • 1
    screen and tmux both have configurable scrollback inside each screen-window. I don't remember seeing anything about keeping scrollback on disk for persistence across reboots, though! That's neat. Three tabs is easy enough to keep track of mentally. I usually have something like 10 on my home desktop, since I do nearly everything from the command line, not a GUI file browser. (playing videos / audiobooks, etc.) I usually have about three shells cded to source code when I'm working on code, though, so that matches up with your usage. – Peter Cordes Dec 17 '15 at 22:38
  • 1
    Anyway, dragging tabs around should make it easy to recover from accidentally closing a tab, since you can put it right back where it goes. – Peter Cordes Dec 17 '15 at 22:39
  • 1
    I don't think a lot of people use them locally, for local shell sessions inside a single terminal emulator tab. IDK, maybe other old-school command-line junkies do it, too. The main use-case is after sshing somewhere. I just got used to using screen, and use it locally as well as on remote sessions. As I understand it, if you don't already have screen in your muscle-memory, learn tmux because screen is old and crufty. I could probably switch to tmux and config it to use all the same keybinds as I use for screen, but screen still works fine for me. – Peter Cordes Dec 17 '15 at 22:48
24

At this point, there's no way to get the tab back. The terminal session is closed, and it no longer has a TTY. There's just no way to reference the tab in order to do anything clever. I'd suggest adding this function to your .bashrc or .profile so that you won't have the issue in the future:

exit() {
    read -t5 -n1 -p "Do you really wish to exit? [yN] " should_exit || should_exit=y
    case $should_exit in
        [Yy] ) builtin exit $1 ;;
        * ) printf "\n" ;;
    esac
}

or, for those of us who use the Z Shell (add it to your .zshrc):

exit() {
    if read -t5 -q should_exit\?"Do you really wish to exit? [yN] "; then
        builtin exit $1
    fi
}

It's a nice little barrier between you and that annoying exit command! Lord knows I've done the same thing many times in the past.

  • 1
    You got it! Now, after 5 seconds (the -t 5 option), the read command will fail, which triggers the exit command following it. – William T Froggard Dec 17 '15 at 16:59
  • 1
    Excellent - thanks - I wish I could give you two up-votes! ;-) – Paul R Dec 17 '15 at 17:04
  • 1
    @PaulR: You don't need to alias exit if you're using Bash. You can put your script in ~/.bash_logout. – Paused until further notice. Dec 17 '15 at 23:53
  • 2
    @DennisWilliamson: interesting idea, but I'm not sure how you'd cancel the logout from within .bash_logout ? – Paul R Dec 18 '15 at 7:05
  • 3
    @PaulR: Oops. I failed to consider that! For completeness, you should also alias logout and set IGNOREEOF greater than 1 (or rebind ^D). – Paused until further notice. Dec 18 '15 at 17:55
5

William T Froggard's script did not do what I needed, because generally the only way I get into this situation is via ^D (ctrl+D), and redefining exit did nothing for that situation. For me, Dennis Williamson's suggestion of setting IGNOREEOF was enough. I just added:

# Do not exit on a single ^D, require 2 in a row
IGNOREEOF=1

to my ~/.bashrc file and now (if I'm in the top-level shell and would exit the terminal) the first ^D generates the response:

Use "logout" to leave the shell.

If I type ^D again immediately, the shell exits, so exiting when I want is still easy, but now a single ^D will give me a warning. (If you want, you can set IGNOREEOF to a higher number to require additional consecutive ^D's.)

Also helpful, if I'm in a sub-shell, the first ^D generates the response:

Use "exit" to leave the shell.

Again, an extra ^D will get me out, and now I can tell the difference between exiting a sub-shell and exiting the top-level shell.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .