The IJ Bash Environment is a packaging of part of the way I set up my own bash + xterm environment in Linux. There isn't much code to it, but a little script code can go a long way, and it appears to be sufficiently original to be worth sharing.
There are two components. The first is a little utility
program to display a scrollable menu in an xterm or similar
terminal emulator,
ijmenu
(man page).
In fact, ijmenu
a standalone tool which may be
useful in itself as a minimalist alternative to programs
like whiptail and dialog.
Copy it to any directory in your $PATH
, or,
for a system-wide install, put it in
/usr/bin
and generate a man page like this:
pod2man -c "" -r "`ijmenu -v`" `which ijmenu` \ | gzip -9 > /usr/share/man/man1/ijmenu.1.gz
In operation, it looks like this:
: ~ 15; man ijmenu : ~ 16; ijmenu 1 5 0 zero one two three four five six seven zero one two three four
The rest of the package is in
ij.bash.
To use this, copy it to (for example) your home directory
and add the following line to your ~/.bashrc
to source it:
. ij.bash
If you're the system administrator, you can of course
put it somewhere like /etc/
.
Now a brief run-through of what it does.
First, it keeps a record of all directory changes, allowing
you to quickly change to previous working directories with
the help of ijmenu
.
: ~ 1; pwd /home/sigrid : ~ 2; cd /usr/lib/perl5/auto/Locale : Locale 3; alias sc='cd ~/scripts' : Locale 4; sc : scripts 5; pushd /var/lib /var/lib ~/scripts : lib 6; d cd ~ cd /usr/lib/perl5/auto/Locale cd ~/scripts
Above, 'd' is aliased to the function ij_rd
.
Note that it doesn't matter what command is used to effect
the directory change - whether it be an ordinary cd
,
an alias or anything else.
The prompt string (bash's PS1
) may look strange.
It is chosen to allow easy copying and pasting of commands:
if you copy a whole line using a mouse triple-click and paste
it to repeat the command then the prompt will be ignored by
bash - since ':
' is a shell builtin command that
does nothing, and what follows it, up to the terminating ';',
are treated as its arguments.
This is especially useful if you want to copy a command to paste into another terminal, or if you want to copy a series of commands: provided they are not separated by output, you can repeat all the commands by doing a single block copy and paste.
The prompt is kept deliberately short, with the full directory path and the time the prompt appeared being put in the title bar of the terminal window. The time allows you to see the time the last command completed (which can be interesting if you leave a long-running command executing while you go and do something else). More helpfully, together with the directory, it allows you to quickly identify the terminal session you want from a window list:
What about PS2
?
Some indication that the current command is incomplete is needed,
but it would preferably be "transparent" like the PS1 prompt, so
that a multiline command could be copied and pasted in one block.
One approach is to use one or more spaces.
This is transparent in most cases, but indents the following lines
more on each successive copy and paste.
A truly transparent alternative is a colour splash prompt:
: bin 15; for i in ij*
: bin 15; for i in ij* do echo "file: $i" done file: ijmenu : bin 16;
I sometimes copy the contents of a terminal (the commands and their output) into a file. This can be a boon for sysadmin-type tasks, for example, to record and so later be able to repeat the necessary configuration steps to install some piece of software without reading through all the documentation again, or for demonstrational purposes, or to report a bug, etc. For this, the "filter terminal session" function preserves lines starting with a prompt unchanged, while turning output into comments. Here's a brief snippet to illustrate (note also the different colour prompt for user root):
: / 15; cd /etc : etc 16; cp fstab fstab.bak : etc 17; vi fstab : etc 18; # here's what I changed: : etc 19; diff fstab.bak fstab 5c5 < LABEL=lenny / ext3 errors=remount-ro 0 1 --- > LABEL=squeeze / ext3 errors=remount-ro 0 1 : etc 20; : etc 20; fts >> ~/config.log
At this point, the commands up to the "fts
" are
copied and pasted, and thus passed through fts
into the log file.
The result is:
: etc 21; tail ~/config.log cd /etc cp fstab fstab.bak vi fstab # here's what I changed: diff fstab.bak fstab # 5c5 # < LABEL=lenny / ext3 errors=remount-ro 0 1 # --- # > LABEL=squeeze / ext3 errors=remount-ro 0 1 : etc 22;
To preserve the prompts on command lines, use "fts -p
".
Consistent with the above, "h
" is an alias for an
alternative to the history function: it wraps the history numbers
in the same manner as the prompt, to allow for quick triple-click
or block copying of commands into the same or another terminal:
: ~ 23; h 9 : 15; cd /etc ## cd /etc : 16; cp fstab fstab.bak : 17; vi fstab : 18; # here's what I changed: : 19; diff fstab.bak fstab : 20; fts >> ~/config.log : 21; tail ~/config.log : 22; cd - ## cd ~ : 23; h : ~ 24;
Note the extra comments:
any command which changes the working directory is highlighted with
an extra "## cd
..." so that it's easy to see the
directories in which the commands were executed.
In fact the directory change mechanism, as currently implemented,
gets the directory history from this annotated history output.
In addition to the above, there are functions to save and restore (replay) the working directory history. See the contents of ij.bash for these.
There are some limitations.
For example, it is assumed that directory names don't have spaces
in them (mine don't), and the "fts
" function does not
attempt to distinguish the second and subsequent lines of
multiline commands from the output of those commands
(with an effectively empty PS2 prompt, that would be difficult to do).
For me, these issues aren't significant.
Directory changing: Though some swear by Ctrl-R, there seems to be a general consensus that bash's built-in mechanisms for remembering and changing directories are inadequate, and many Linux/Unix shell users have come up with their own approaches to correcting this. Two tools based on the idea of bookmarking directories are Stijn van Dongen's Apparix, one of the more sophisticated alternatives, and cdargs, which additionally provides a full-screen directory browser. Even if you're a bookmarking kind of person, the simple directory-changing functionality described here is to some extent complementary, insofar as it allows you to swap very rapidly within a group of directories you happen to be working in right now without bookmarks or aliases.
History: the annotation of bash's command history to show changes in the working directory is based on Dennis Williamson's solution to a problem posed by Lajos Nagy.
Prompts: Though I haven't seen anyone using the truly empty
prompt (above, that's the one I called a "colour splash prompt"),
the idea of a PS1
prompt that makes for easy
triple-click copy and pasting is relatively well known
– see the
Bash Prompt HOWTO).
— Michael Breen, 2011.3.17