[comp.unix.questions] Using exit in a Bourne shell script

iunix1@almsa-1.arpa (Will Martin) (07/19/88)

Back in February, there were some Info-UNIX discussions under the above
subject regarding methods of replacing the normal CTRL-D logoff with 
a special script or procedure. One of the contributors mentioned this:

> From: Kathy Vincent <kathy@bakerst.uucp>
> 
> 	trap '$HOME/.logout' 0
> 
> Which is to say, "when you receive the logoff signal, execute $HOME/.logout
> first and THEN log off."

On our Sys V Unisys/Sperry I can do this, and get the ".logout" script to
execute when I hit a CTRL-D at the shell. It runs whatever I put in
".logout" and then logs me off the system. However, what I really want to
happen is to have a script execute that will then ask me "Do you REALLY
want to log off?" and then either return me to my shell, or allow me to
log off, depending on my answer. I want to do this because I am
constantly spawning subshells to do this or that task, and using CTRL-D
to end them. I often hit a CTRL-D at my top-level shell and get logged
off when I really did not want to log off -- I thought that I was under
my message-reading program, for example, and wanted to get back to it.
So I am willing to take the extra time to confirm it when I am finally
done and really, truly want to log off. I had thought at first that I
could do something with stty "eof" or suchlike settings that could make
my actual logoff character someting other than CTRL-D, so I could use
that to kill subshells, but not my top-level shell, but I've been told
that won't work.

Anybody have any advice on this subject? Is there a clean way to do what
I want? Or even a dirty way -- I'm pretty sloppy... :-) Can a script
executed at the "trap 0" point get back to the shell where the signal
originated, or is it too late by then? If so, could it cause another
top-level shell to be spawned, keeping all the environment I had before?

Will Martin
"wmartin@almsa-1.arpa"

maart@cs.vu.nl (Maarten Litmaath) (07/20/88)

In article <16540@brl-adm.ARPA> iunix1@almsa-1.arpa (Will Martin) writes:
\...
\On our Sys V Unisys/Sperry I can do this [trap '. $HOME/.logout' 0],
\and get the ".logout" script to
\execute when I hit a CTRL-D at the shell. It runs whatever I put in
\".logout" and then logs me off the system. However, what I really want to
\happen is to have a script execute that will then ask me "Do you REALLY
\want to log off?" and then either return me to my shell, or allow me to
\log off, depending on my answer.
\... If so, could it cause another
\top-level shell to be spawned, keeping all the environment I had before?

Environment is ok, you're going to lose the local shell variables.
Put the following in your .profile:

	TTY=`tty`
	export TTY
	trap '. $HOME/.logout' 0

Put the following in your .logout:

	/bin/echo -n 'Do you really want to logout? '
	case "`gets < $TTY`" in
		y*)
			echo Bye!
			;;
		*)
			exec xq sh -sh -i < $TTY
			;;
	esac

The TTY stuff is necessary, because sh has already closed your tty before
it's going to source .logout. :-(
The 'xq' program, whose source is below, executes its first argument with
the name of the second argument, causing the sh to believe it's a login
shell.
Good luck with it!

/*
 * xq.c
 */

main(argc, argv)
int	argc;
char	**argv;
{
	if (argc < 3) {
		puts("Wadda ya thinka this!");
		exit(1);
	}
	execvp(argv[1], &argv[2]);
	perror(argv[1]);
	exit(1);
}
-- 
I'd rather live in Russia             |Maarten Litmaath @ Free U Amsterdam:
              than in South-Africa... |maart@cs.vu.nl, mcvax!botter!ark!maart

goog@a.cs.okstate.edu (GOOG ??) (07/20/88)

In article <16540@brl-adm.ARPA> you write:
> ...
>I often hit a CTRL-D at my top-level shell and get logged
>off when I really did not want to log off -- I thought that I was under
>my message-reading program, for example, and wanted to get back to it.
>I had thought at first that I
>could do something with stty "eof" or suchlike settings that could make
>my actual logoff character someting other than CTRL-D, so I could use
>that to kill subshells, but not my top-level shell, but I've been told
>that won't work.
>
I had this problem also, and to combat it I put a line in my .login (not
.logout...) that states:

set ignoreeof

and that does it.  It will allow you to use Ctrl-D from anywhere to quit things
but not to logout.  It forces you to type the word logout to logout.

I hope this is what you were wanting.


Steve Koinm				Internet:  goog@a.cs.okstate.edu  
Systems Administrator				steve@nemo.math.okstate.edu 
Department of Mathematics
Oklahoma State University		UUCP: rutgers!okstate!goog 	
Stillwater, OK  74078
--------------------------------------------------------------------------------
You are magnetic in your bearing--that's why all the nuts cling to you.         

gandalf@csli.STANFORD.EDU (Juergen Wagner) (07/20/88)

How about 
	set ignoreeof
in your .cshrc. This will prevent you from doing what you're fearing, namely
logging out by hitting ^D. If you want to disable ^D just for the login shell,
you could do the "set ignoreeof" in .login, and "unset ignoreeof" in .cshrc.

You may also want to have some kind of depth count in your prompt line.

--Juergen
-- 
Juergen "Gandalf" Wagner,		   gandalf@csli.stanford.edu
Center for the Study of Language and Information (CSLI), Stanford CA

leo@philmds.UUCP (Leo de Wit) (07/21/88)

In article <16540@brl-adm.ARPA> iunix1@almsa-1.arpa (Will Martin) writes:
>Back in February, there were some Info-UNIX discussions under the above
>subject regarding methods of replacing the normal CTRL-D logoff with 
>a special script or procedure. One of the contributors mentioned this:
>
>> From: Kathy Vincent <kathy@bakerst.uucp>
>> 
>> 	trap '$HOME/.logout' 0
>> 
>> Which is to say, "when you receive the logoff signal, execute $HOME/.logout
>> first and THEN log off."
>
>On our Sys V Unisys/Sperry I can do this, and get the ".logout" script to
>execute when I hit a CTRL-D at the shell. It runs whatever I put in
>".logout" and then logs me off the system. However, what I really want to
>happen is to have a script execute that will then ask me "Do you REALLY
>want to log off?" and then either return me to my shell, or allow me to
>log off, depending on my answer. I want to do this because I am

  [some stuff deleted]

>Anybody have any advice on this subject? Is there a clean way to do what
>I want? Or even a dirty way -- I'm pretty sloppy... :-) Can a script
>executed at the "trap 0" point get back to the shell where the signal
>originated, or is it too late by then? If so, could it cause another
>top-level shell to be spawned, keeping all the environment I had before?

I tried the 'trap ....' command and noticed that in the .logout script
a read from the terminal was not honoured, i.e. read answer didn't put
anything in answer (there was no waiting for my response). Obviously
the stdin of the shell has already been closed. Then I tried to fake it
by reading from /dev/tty; you have to do something like

for i in 1
do
    read answer
done </dev/tty

because read cannot have redirection. This time there is a wait, but
again answer is empty (probably because this time read gets executed in
a subshell).  There is also the problem to get a correct standard input
filedescriptor for a new shell I think if the current one is closed
(not sure about that).

However, the following worked (a bit 8-):

1) Put in your .profile:

exec 3<&0                   # Dup stdin
trap '. $HOME/.logout' 0    # note the .; better to let you shell execute it

2) Put in .logout:

------------------     .logout starts here    ------------------

echo -n 'Do you really want to logout [Y/n] ? '

exec 0<&3
read answer

case $answer in
n|N) exec $SHELL;;
*) exec 0<&-;;
esac
------------------     .logout ends here    ------------------

Of course the SHELL environment variable has to contain the name of
your favourite shell. The stdin descriptor is dupped back from 3 (maybe
it is better to use a symbolic name than 3).
The problem I haven't solved yet is to re-install the trap after the
exec (a solution that works for /bin/sh is to exec a small program
instead that execs /bin/sh with argv[0] == "-sh"; the - guarantees that
the .profile is read).
In any case however, all environment variables are inherited from the
current shell. I hope it is sloppy enough for you 8-)!

Have fun!

           Leo.

aeb@cwi.nl (Andries Brouwer) (07/22/88)

In article <16540@brl-adm.ARPA> iunix1@almsa-1.arpa (Will Martin) writes:
> I often hit a CTRL-D at my top-level shell and get logged
> off when I really did not want to log off.

If you are using ksh or csh: set ignoreeof .
For the Bourne shell: you might try to use another prompt on
the outermost level (set PS1="@@@ " in your .profile, and do not export it).

-- 
      Andries Brouwer -- CWI, Amsterdam -- uunet!mcvax!aeb -- aeb@cwi.nl

leo@philmds.UUCP (Leo de Wit) (07/24/88)

In article <3733@okstate.UUCP> goog@okstate.UUCP (GOOG ??) writes:
  [stuff deleted]...
|I had this problem also, and to combat it I put a line in my .login (not
|.logout...) that states:
|
|set ignoreeof
|
|and that does it.  It will allow you to use Ctrl-D from anywhere to quit things

In article <4664@csli.STANFORD.EDU> gandalf@csli.stanford.edu (Juergen Wagner) writes:
|How about 
|	set ignoreeof
|in your .cshrc. This will prevent you from doing what you're fearing, namely

  [stuff deleted]...

Boys, read the subject line. It says: ... in a Bourne shell script.
set ignoreeof is csh stuff.

        Leo.

dan@maccs.McMaster.CA (Dan Trottier) (07/26/88)

In article <16540@brl-adm.ARPA> iunix1@almsa-1.arpa (Will Martin) writes:
>Back in February, there were some Info-UNIX discussions under the above
>subject regarding methods of replacing the normal CTRL-D logoff with 
>a special script or procedure. One of the contributors mentioned this:
>
>> From: Kathy Vincent <kathy@bakerst.uucp>
>> 
>> 	trap '$HOME/.logout' 0
>> 
>> Which is to say, "when you receive the logoff signal, execute $HOME/.logout
>> first and THEN log off."
>
>Anybody have any advice on this subject? Is there a clean way to do what
>I want? Or even a dirty way -- I'm pretty sloppy... :-) Can a script
>executed at the "trap 0" point get back to the shell where the signal
>originated, or is it too late by then? If so, could it cause another
>top-level shell to be spawned, keeping all the environment I had before?

Here is how we do this around here. You must remember that your .login file
is read after reading your .cshrc file at login. In you .login file you
place the following "set ignoreeof" and in your .cshrc file you place 
"unset ignoreeof".

So at login the ignoreeof will be set by your .login file and thus will
prevent you from loging out via a ctrl-D. If you start a new sub-shell
the .cshrc file is read and the "unset ignoreeof" will allow you to use
ctrl-D to exit that shell.


Sorry if this has already been answered.

dan


-- 
       A.I. - is a three toed sloth!        | ...!uunet!mnetor!maccs!dan
-- Official scrabble players dictionary --  | dan@mcmaster.BITNET

gwyn@brl-smoke.ARPA (Doug Gwyn ) (07/29/88)

In article <3733@okstate.UUCP> goog@okstate.UUCP (GOOG ??) writes:
>In article <16540@brl-adm.ARPA> [Martin at Almsa-1] write[s]:
>>I often hit a CTRL-D at my top-level shell and get logged
>>off when I really did not want to log off -- I thought that I was under
>>my message-reading program, for example, and wanted to get back to it.
>I had this problem also, and to combat it I put a line in my .login (not
>.logout...) that states:
>set ignoreeof

Ahem, that's not a Bourne shell you're using (see the Subject line).

The answer is, the best way to obtain accidental logout protection
for the Bourne shell is to get BRL's version and add "set -E" to
your .profile.