How can I get a confirmation before I exit screen (when typing exit on the command-line). Is this possible?
GNU Screen – How to Get Confirmation Before Exiting Screen
exitgnu-screen
Related Solutions
I know this isn't answering the exact question you have, but I normally jump to miniterm.py
when presented with this kind of device because I've never found a way to do what you want with screen.
miniterm.py
is minimal like screen and does the 'right thing' by default with \n
. On the downside, my fingers don't know how jump around, quit and log, etc, so I still live in hope there's a way to do the right thing in screen
On OS X:
miniterm.py /dev/tty.usbmodem1412
gives me nice output when screen would have scrawled all over the place.
pySerial comes with miniterm.py
as far as I understand
Note that screen
is a terminal emulator. So your question is a bit like asking how can I start xterm
from gnome-terminal
and have what was last displayed in xterm
visible in my gnome-terminal
when xterm
exits.
Now the difference between xterm
and screen
is that while xterm
uses the X protocol to draw its screen, screen
uses a host terminal.
By default, screen
will clear the screen of its host terminal to display its own emulated terminal and where available will use the alternate screen (before clearing) of that host terminal, so that upon termination, it can restore the host terminal state as it was before starting.
So what you see is not screen
clearing the screen upon leaving, but restoring the host terminal's main screen. The content of the screen
window that was last displayed is still there on the alternate screen. With xterm
, you can have a look at it by selecting Show alternate screen in the Ctrl+MiddleClick menu.
If the host terminal doesn't support an alternate screen (like vt102 ones), it obviously can't do that. Instead, it does nothing, which is basically what you want.
So, what you can do is tell screen
that the host terminal doesn't support an alternate screen. For that, you can add to ~/.screenrc
:
termcapinfo * ti=:te=
Which says: for all possible host terminals (*
, matched against $TERM
), override the termcap/terminfo
database to say that for those terminals, the escape sequences to enter or leave the alternate screen are the empty string.
ti
and te
do not exactly mean alternate screen. From https://www.gnu.org/software/termutils/manual/termcap-1.3/html_node/termcap_39.html:
ti
(smcup
interminfo
)
String of commands to put the terminal into whatever special modes are needed or appropriate for programs that move the cursor nonsequentially around the screen. Programs that use termcap to do full-screen display should output this string when they start up.
te
(rmcup
interminfo
)
String of commands to undo what is done by theti
string. Programs that output the `ti' string on entry should output this string when they exit.
But that translates to the alternate screen for most terminal emulators (specically, in xterm
it's alternate screen and saving/restoring of the cursor position)
Best Answer
I approached this by masking the
exit
command with a function; the function checks to see if you're within screen, and if you're the only child process left of that screen process.You would have to include that function as part of your (bash) profile, e.g.
~/.bash_profile
. When starting screen, it will (unless told otherwise), start an instance of your $SHELL. That shell will be a child of a screen process. When exiting from a child shell, the above code checks to see how many processes are children of the current shell's parent process. From the inside out:$(ps -o ppid= -p "$$")
-- asks for the parent PID (adding the=
suppresses the header line) of the current process ($$
)$(ps -o pid= --ppid ... | wc -l)
-- asks for the list of PIDs (again without the header) whose parent PID is our parent, then counts the number of lines of outputIf it looks like we're the last child process of a screen session, it prompts for confirmation; if the response begins with the letter
y
, the function calls the "real"exit
command to exit the shell; otherwise, the function ends without exiting the shell.If we're not the last child process, the function goes ahead and exits normally.
A couple notes as I developed this:
I initially had more tests in the
if
line to see if we are within a screen session, including seeing ifSTY
is populated and forSHLVL
being greater than 1. screen sets STY, and bash will increment SHLVL, but neither of those variables are read-only, so the test is not strong enough to be useful.screen also sets a
WINDOW
variable, but checking it for0
is not reliable; you could open two windows and then close window0
, leaving window1
as the last window.Entering EOF (usually Control+D) will, by default, cause the shell to immediately exit, bypassing this wrapper function. The best workaround I know would be to set the variable
IGNOREEOF
to some non-zero value; that will only delay the shell's inevitable exit, though.Because I used so many bash- (and GNU procutils-) specific features above, I wanted to also provide a POSIX-conformant solution. The
ps
line changes to aps ... | grep -c
scheme in order to capture the number of processes with a specific parent PID. The other change is to re-work theread -p
into a separate prompt andread
.