7.9 Show Subshell Level with $SHLVLIf you're like me, when you start a shell escape (30.26 ) or any subshell (38.4 ) , you can forget that you aren't in your login shell. Your shell history (11.1 ) might get confused, shell variables (6.8 ) may not be set, and other problems may come up. tcsh (8.3 ) and bash (8.2 ) have a built-in SHLVL environment variable (6.1 ) that lets you track how many subshells deep your current shell is. This article shows how to set up SHLVL for the C shell. (You could use a similar setup with ksh , if you set its ENV (6.3 ) environment variable.) tcsh (and the csh setup below, too) also have a shlvl shell variable with the same information. In your top-level shell, the value of # If this is a subshell, put shell level in prompt: if ($SHLVL == 1) then set prompt="${USER}% " else set prompt="($SHLVL) ${USER}% " endif bash doesn't need an if because login shells read your .bash_profile (or .profile )-and subshells read your .bashrc . Here are commands to set the prompts I mentioned above: PS1='\u\$ ' ...for the .bash_profile PS1='($SHLVL) \u\$ ' ...for the .bashrc Both bash and tcsh use the same environment variable, so you can start one shell from the other and the level will be correct. Here's how to make csh work with tcsh and bash -or work on its own, if you don't use the other shells. Put the following lines in your .cshrc file: [1]
Does your account run a windowing system that's started from your top-level shell startup file (like .login )? If it does, lines like the examples below (these are for .login ) will reset SHLVL so that the shell in the window will start at a SHLVL of 1-and act like a top-level shell. This code assumes that your first login shell starts on the tty named /dev/console , and that the windows that open won't have a tty named /dev/console . (If you aren't sure, check who (51.4 ) .) You may need to adapt this. The trick is to make SHLVL 0 (zero) before you start the windowing system. When the windows' shells start, they'll raise SHLVL to 1: # If on workstation console, bury this shell and run X right away: if ("`/bin/tty`" == /dev/console) then setenv SHLVL 0 xinit # Start X window system endif Getting this to work right in every situation (rsh (1.33 ) , su (22.22 ) , shell escapes (30.26 ) - both interactive and noninteractive, subshells, window systems, at jobs (40.3 ) , and so on) can be a challenge (2.7 ) ! It takes a little planning. Sit down and think about all the ways you start subshells... which subshells are interactive and which aren't... and whether they'll get SHLVL passed from their parent process (if you aren't sure, test that with an env or printenv command (6.1 ) ). Then plan which kind of shell needs which SHLVL settings. If it gets too complicated, make it work in most cases! If you use many subshells, this system is too handy to ignore. - |
|