A collection of assorted shell snippets and other useful bits. Some of these are shell specific (I use bash), so copy paste at your own risk.
- The directory stack (pushd, popd, dirs)
- Job management, aka Running tasks in the background (fg, bg, jobs, wait)
Bash has a directory stack. This can be used to suplement cd -
, since it goes deeper than just the previous directory.
See man 1 bash
for the full set of options.
pushd <dir>
changes directory to <dir>
, and pushes the old working directory onto the stack. It then prints the stack (note that the first element in the printed stack is always the current directory).
popd
pops the first directory off the stack, and changes to the next directory
dirs
prints the current stack
You can also use dir -c
to clear the stack.
Here's a short example
$ pwd
/etc
$ pushd /var
/var /etc
$ pwd
/var
$ pushd /
/ /var /etc
$ pushd /var/log
/var/log / /var /etc
$ dirs
/var/log / /var /etc
$ popd
/ /var /etc
$ popd
/var /etc
$ popd
/etc
$ popd
bash: popd: directory stack empty
In bash, I know of 2 ways to run a command in the background:
- Suspend a running process with the suspend charachter (typically
ctrl-z
) or the delayed suspend charachter (typicallyctrl-y
) (suspend when it tries to read input from the terminal), then resume it in the background withbg
- Execute a command with a trailing
&
(e.g.long-running-task &
)
Both of these will leave you with a usable shell, but your task will still be running. It won't use stdin of your shell (if it asks for input it will most likely hang), but it will use stdout, so you might want to use quiet flags if you don't want it randomly printing.
When you put a job in the background, the shell will print something like [1] 25647
. This indicates that the job you just started (or resumed) is job 1, and the id of the last process in the pipeline is 25647.
Typing fg
will bring the top job into the foreground. You can resume a specific job. To resume job 1, you'd use fg %1
or just %1
. This syntax can also be used to resume a suspended task in the background, bg %1
or %1 &
.
jobs
will list the state of all jobs.
wait
will cause the shell to wait for all the running jobs to change state.
An example use case:
# Run `do_command` on every server, in parallel (mostly)
for host in host{001..100}.example.com; do (ssh $host "do_command") & done
# Wait for all of the ssh processes to exit (or at least change state) before resuming the shell
wait