29

Let's say I start in my local account:

avindra@host:~>

then I switch to root:

host:~ #

Then I switch to oracle:

[ oracle@host:~]

Is there a way for me to drop back into the root shell (the parent), without logging out of the oracle shell?

This would be convenient, because the oracle account does not have sudo privileges. A typical scenario with oracle is that I end up in /some/really/deeply/nested/directory, and all kinds of special environment variables are set in particular ways.

Here comes the problem: I need to get back into root to touch some system files. Yes, I can log out of oracle to get back to root, but at the cost of losing my current working directory and environment.

Is there a way to "switch" to the parent shell using known conventions?

  • If you are using a gui desktop, you can just open another terminal window or tab or even switch to another virtual console. If not, use screen as stated in one of the answers. – Joe Dec 26 '14 at 19:55
  • I'll look into screen, I haven't used it before. As for tabs, I prefer to use one tab for host. I find a workflow that entails multiple tabs per host to be cumbersome. I do a lot of work in clustered hosts / distributed systems, so even having one tab per node in the cluster can get confusing. In my mind, one tab = one discrete host. – Avindra Goolcharan Dec 26 '14 at 20:08

3 Answers3

41

You can simulate a CTRL-Z (which you normally use to temporarily background a process) using the kill command:

[tsa20@xxx01:/home/tsa20/software]$ kill -19 $$

[1]+  Stopped                 sudo -iu tsa20
[root@xxx01 ~]# fg
sudo -iu tsa20
[tsa20@xxx01:/home/tsa20/software]$

bash just traps the CTRL-Z key combination. kill -19 sends SIGSTP to the process which is effectively the same thing.

Bratchley
  • 16,684
  • 13
  • 64
  • 103
  • 1
    In `zsh` you can just run `suspend`. – Mikel Dec 19 '14 at 20:10
  • 3
    @Mikel, `zsh` or `csh`, `tcsh`, or `bash`, or the Bourne shell or `ksh`... (in `ksh`, _suspend is an alias for `'kill -s STOP $$'`_ (note the bug with the missing quotes around $$)). – Stéphane Chazelas Dec 19 '14 at 23:19
  • I can't run `suspend` after doing a `sudo -i` ([Output](https://dpaste.de/oSS8)) in bash. – Bratchley Dec 20 '14 at 03:32
  • Just reproduced [the same error message](https://dpaste.de/vki5) in `zsh`. Adding `-f` makes it work though. – Bratchley Dec 20 '14 at 03:36
  • Beautiful. This is going to save me so much time. Can't wait to show it to the coworkers. – Avindra Goolcharan Dec 20 '14 at 04:49
  • 1
    @StéphaneChazelas Does that really make a difference with a variable that's almost certainly guaranteed to contain a numeric value? – alexia Dec 20 '14 at 14:18
  • @nyuszika7h, not-quoting variables is the split+glob operator. It makes no sense at all to invoke it here. The behaviour of the split part depends on the current value of `$IFS`. See also [Security implications of forgetting to quote a variable in bash/POSIX shells](http://unix.stackexchange.com/q/171346/22565). – Stéphane Chazelas Dec 20 '14 at 16:17
  • @StéphaneChazelas `$$` is a read-only variable, though, and you can make assumptions about its value. That said, I **do** quote those variables when using them. – alexia Dec 20 '14 at 16:20
  • 2
    `bash` does _not_ trap CTRL-Z, when you press CTRL-Z, your terminal emulator sends a `^Z` character (0x1a) to the master side of the pty device. The _line discipline_ of the pty driver then sends SIGTSTP to the foreground process group of the terminal. Until then `bash` is not involved at all. That SIGTSTP may cause the process group leader to suspend and _then_ the `wait()` that `bash` does on it will return. – Stéphane Chazelas Dec 20 '14 at 16:23
  • 5
    Note that there's no guarantee that `19` will be the number of SIGTSTP. Use `kill -s TSTP` or `kill -s STOP` (TSTP can be trapped or ignored, STOP cannot). – Stéphane Chazelas Dec 20 '14 at 16:24
  • 2
    @nyuszika7h, `$$` may be readonly, but `IFS` is not. Try `IFS=0123456789; suspend` in `ksh` for instance. – Stéphane Chazelas Dec 20 '14 at 16:26
  • @StéphaneChazelas I didn't think of that. That's a good point. – alexia Dec 20 '14 at 16:27
3

Csh, bash, ksh, zsh, have a suspend builtin command (or alias, in ksh) that does exactly that. This command is mostly equivalent to sending a TSTP signal to the shell; bash and zsh do a bit of additional signal handler and juggling, and in these shells the suspend command works even if the shell is currently ignoring TSTP.

You can also send the signal to the shell manually with kill -STOP $$.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
0

I would also suggest that you could use (install if needed) a program called [screen][1] that let's you have multiple terminal windows open. It was designed for TTYS so it works just fine without needing X. You can use keyboard shortcuts to switch between terminals and disconnect and logout, leaving your terminals still running, then log back in and reconnect to them.

I believe most Linux distributions have packages for this program, and I have used packages on Solaris for it. Worst case of course is you can install from source.

qneill
  • 113
  • 4