dynamide bash-menu is a menu system for bash which keeps lists of
- directories you wish to navigate to
- command lines you wish to execute
- spaces, which group directories and commands by project
Here's a screenshot showing launching the directory menu, then switching to the command menu:
You use the menu to select from these lists. Selecting a directory from a menu changes to that directory. Selecting a command from a command menu executes that command. You can use the menu or the command line to add to, remove from, and edit these lists.
A fancy bash-prompt is also provided, which gives you options to display on one line the title, user, host, pwd, and git-status. See Using the title command.
After you install bash-menu and log in, you'll have a custom prompt, and some new commands:
- d directory changer
- da add a directory to the list
- m menu of executable command-lines
- ma add a command to the list
- catall cat all text files in current directory with a colored line between each.
- title set the title, user, or hostname in a multi-line, colored PS1 bash prompt.
Philosophy / Workflow
Why do you want a bash menu?
- You are a whiz at
history, tab-completion, expansion, reverse-search... but you still have to ask: what am I doing here, how did I get here, and what do I do next?
- you work on several projects, and having them all together in one history list doesn't help
- you work in multiple terminals simultaneously, and synchronizing the histories doesn't help
- you prefer command-line tools for their configurable options, but so many options to remember!
- you hate typing long paths or aliasing everything
- you run multiple, complicated command lines repeatedly, but they aren't quite ready for putting into scripts yet.
Execute command-by-command at the command-line, until you get one that does just what you want it to do. Add that last command by executing
ma which grabs the last item from your history and adds it to the command menu.
You have completed a prototyping session locally, and would like to write a script to capture all the steps you did. List your history, then cherry-pick the commands you want using
history 473 cd /src/myproject 474 ./ant 475 cd /var/log/foobar 476 dir 477 rm /var/log/foobar/* 478 /usr/local/bin/restartdb
Now just grab the ones you want, then bring up the command list in EDITOR:
ma !477 ma !473 ma !474 ma !478 d m e
You work in many directories, and often use paths like
./exec-foo. To use your history, you need to know which directory you were in. If you
pushd incrementally, your history is not much help here. If you use bash-menu to store the path and the command together, you have a re-useable item that is quicker to create than a script, but more reliable than using
cd ~/bin dir cd tomcat7.dm dir cd conf vi server.xml cd .. bin/startup.sh ma -cd
Now when you type
m you'll see something like this item at the bottom of your command menu:
7: cd /Users/laramie/bin/tomcat7.dm ; bin/startup.sh
How did that work? Well, the
ma command has a built-in option
-cd to add the
cd ...; for you. It automatically uses the last item on your history if you specify nothing. It is effectively doing this (which you can also type in if you want):
ma cd `pwd` \; !!
Now, any time you want to start tomcat, just do
Set up each project with scripts and buildfiles in the appropriate directories. Mark these scripts and directories using bash-menu in one space, using menu separators to group commands by area. The menus serve to remind you where the key build directories are, and the commands you'll need once you are there.
You work on multiple projects, and have many command-lines, scripts, directories, and builds to remember. Store each project under a
space, and switch between spaces using bash-menu. the command
d s brings up the space menu from the command-line, and from a bash-menu directory or command menu prompt, you can just type
s. When you change spaces, your directory list and your command menu change. When you are in another terminal or another project, just navigate to the space you want.
Getting the source
On GitHub, mash on the "Download ZIP" button, and extract to
~/.bash-menu, or use wget or curl:
cd ~ curl -o master.zip https://codeload.github.com/dynamide/bash-menu/zip/master unzip master.zip mv bash-menu-master/ ~/.bash-menu/
Or, checkout bash-menu from GitHub:
cd ~ git clone https://github.com/dynamide/bash-menu.git .bash-menu
cd ~ git clone firstname.lastname@example.org:dynamide/bash-menu.git .bash-menu
Then pull in the bash-menu from your bash profile, by sourcing in the bash menu, e.g.
You can source with
All of the shell aliases created by bash-menu are defined in
$DYNAMIDE_MENU/aliases). Please review these aliases before launching.
The next time you log in, you'll have a custom prompt, and some new commands. Try the main command
d for example.
Here is a sample bash prompt on two lines with current working directory, and git status:
Optional Installation Locations
By default, the above check-out will leave you with a new, hidden directory in your home directory, that is,
or something like
/home/laramie/.bash-menu/. bash-menu knows about this because it sets DYNAMIDE_MENU in
If you checked out to some directory other than
~/.bash-menu, for example
~/.my-menu/ then you need to do two things to connect bash-menu to your shell.
- Edit this file, on the line where it sets DYNAMIDE_MENU (by default it is
DYNAMIDE_MENU=~/.bash-menu), so that bash-menu will know where its home directory is.
- Then, in your ~/.bash_profile source in the bash-menu control file we just edited:
Help in bash-menu
To see help, run with
h which will dump out usage.
To see help on options:
d h options
To see all the options and their alternate spellings, see:
d h aliases
To see the current configuration, see:
d h info
To get started, just type
d at your new prompt. From there you can choose a listed item by typing it's number.
Here is the dynamide bash-menu being used to change to directory 6 on the menu:
Note that it shows you the directory you chose, "/Users/vcrocla/src/dynamide/build/resource_root", and then a quick "ls" of that directory, then it changes to that directory. You can tell because the fancy bash prompt has changed and now shows the current working directory as /Users/vcrocla/src/dynamide/build/resource_root, and the git status in that directory is (master) which means we are on git branch "master" with no pending pulls or pushes.
From menus such as the directory menu, you can type another menu option. You can type
? to see the mini-help of sub-commands at this menu.
You can choose options on the command line, and skip the menus. You can also choose some options after you have launched bash-menu and are sitting in a menu, where you are prompted for a choice. If you type a number from the list of choices, you will get that choice. But there are also sub-commands at these menus. These mirror options available on the command line. So you could, for example, launch right into your command menu like this:
Or, you could launch the directory menu, then change to the command menu with this sequence:
that is, typing
d at your bash prompt, then the
Enter key (or
Return key) then typing
m at the choose dir> prompt, then
Here is an actual example:
The sub-commands take an option form:
-h, a single-letter form:
h, and a word form:
Here are all the sub-command options and their equivalents (-c and -s are completely equivalent):
The option form or the cmd form may be used on the command line, or as sub-commands.
Help takes subcommands
info, or their alternate names listed above. For example:
d h info
edit sub-command is context-sensitive, and will launch your EDITOR or VISUAL editor to let you edit the correct menu.
On the command line, using these options could look like these examples below. Eeach group of commands is equivalent, so
d m is the same as
d a # Add to your directory list d e # Edit your directory list d m # Show your command menu d -m d m e # Edit your command menu d m -e d m edit d s e # Edit your spaces menu d s -e d -s edit d -s -e d s edit
And so on.
d -ma takes a special option flag,
-cd that adds a
cd to the current directory before the command you are adding.
d -ma -cd #adds the last shell command to your command menu with a cd `pwd` before it. d -ma -cd !! #adds the last shell command to your command menu with a cd `pwd` before it. d -ma -cd !480 #adds shell history command number 480 to your command menu with a cd `pwd` before it. d -ma -cd bin/make #adds 'bin/make' to your command menu with a cd `pwd` before it.
This works with the alias
ma like so:
ma -cd ma -cd bin/make
NOTE: There is no alias for -cd, so you can NOT do this without the hyphen on -cd:
d -ma cd /bin/mycommand.
In other words:
d -ma -cd /bin/mycommand
d -ma cd /bin/mycommand
Using the title command
bash-menu comes with a custom PS1 bash prompt. This prompt can show you:
To see all the options, type
Here is a sample of what setting various options does to your prompt:
In these examples, my user name is "vcrocla", my host is "SFCAML-G2XFD56", which I override with the fake hostname "myhost".
The title (appears at left of the first line) is any placeholder that reminds you of what this shell was for. If you use -w, or -window, the title is also sent to the shell window's title bar.
My directory "
/src/tagonomy" is a git repository, and its git status in that directory is (master) which means we are on git branch "master" with no pending pulls or pushes. My directory "/src/dynamide" is also a git repository, and also is on branch "master".
You'll also see the numbers of commits ahead/behind if you are not up-to-date. (Thanks to the authors who wrote
git-branch-status, listed in our NOTICE file.)
Here is what it looks like when you are ahead:
If you type
git status you'll see why:
Here is what it looks like when you are ahead and behind:
If you type
git status (I have it aliased to
st) you'll see why:
To customize your prompt, call
title in your ~/.bash_profile after you source in ~/.bash-menu/.bash_profile:
|title -user -nohost -title Lappy -window|
You can edit your menus in two ways:
- using the command-line args or sub-commands in menus, and
- using your console editor such as
- using your console editor such as
For case (2), bash-menu will launch your EDITOR or VISUAL editor on the appropriate file. Just edit, then save normally. Files contain non-blank lines or separators.
|d x||launches the delete menu for directory lists|
|d x 3||deletes directory list item 3|
|d mx||launches the delete menu for commands|
|d mx 3||deletes command menu item 3|
|d m x||launches the delete menu for commands, using submenu|
|d ma||add to the command menu, using command-line|
|d m a||add to the command menu, using submenu|
|d e||launch EDITOR for directory lists|
|d m e||launch EDITOR for the command menu|
|d s||launch the space chooser|
|d s e||launch the space editor|
Separators are three hyphens alone on one line, like this:
/some/directory/on/dirlist --- /bin/probe --- /other/dirs /other/dirs/bin
Separators display in your menus as blank lines. So the above menu renders as:
You can also put line-separating labels in, which will be displayed in your menu in highlight color, minus the leading
---. You can use more
- characters on that line, or any other printable character. Here I'm using
= characters to help visually break up the menu.
/some/directory/on/dirlist ---=== Area 51 === /bin/probe ---=== Area 52 === /other/dirs /other/dirs/bin
In case you want to use bash-menu in a script itself, you'll want to use the quiet option:
-q which suppresses all but the most essential output. The opposite is
-v which gives debugging info.
To keep things simple, you may wish to avoid aliases in your scripts and use the full names of things, e.g. instead of calling
bash-menu-d which is the name of the main bash function that
d is aliased to.
Remember that all
m commands are relative to the current space, so you should change to your space first, or set it using DYNAMIDE_SPACES_LIST. You can programmatically set your space, e.g. by calling
d s 0 to select space
d s 1 to select space
1. (NOTE: $DYNAMIDE_MENU/space.index is written out for you. However, you can overwrite it with the zero-based index of the space you want to use in DYNAMIDE_SPACES_LIST. Usually,
d s 0 is the preferred way.)
After you call to set the space, e.g.
d s 0, the following values are exported to your shell:
DYNAMIDE_DIRLIST_LIST DYNAMIDE_MENU_LIST DYNAMIDE_MENU_SPACE_INDEX
Here is how to set the env var to point to a specific space list, e.g.
Here is how to programmatically get the menu line for an item in a file:
line=`bash-menu-getFromList $DYNAMIDE_SPACES_LIST $DYNAMIDE_MENU_SPACE_INDEX`
Here is how to programmatically get the bare menu line for an item in a file without the index being displayed:
line=`bash-menu-getFromList $DYNAMIDE_SPACES_LIST $DYNAMIDE_MENU_SPACE_INDEX bare`
This technique can be used to read a line from any of the files: directories.list, menu.list, spaces.list, by passing the list name, and the zero-based index of non-separator lines. (Blank lines are not allowed in the list files.) For example, get the 3rd item (index 2) from your directory list:
line=`bash-menu-getFromList $DYNAMIDE_DIRLIST_LIST 2 bare`
For example, get the 4th item (index 3) from your menu list:
line=`bash-menu-getFromList $DYNAMIDE_MENU_LIST 3 bare`
###Show your directory menu
###Show your command menu
###put shell history item 467 (expanded) into your menu
d -ma !467
###put a command into your menu using the alias
ma (installed in ~/.bash-menu/aliases)
ma find . -iname '*my-file.*'
###chose menu item 2 and execute it
d -m 2
###chose menu item 2 and execute it
###put a separator into your menu using the special string ---
###put a separating label into your menu using the special string ---
ma ---Build RestReplay
Everything after the
--- is treated as the label. Note that you don't need quotes around "Build RestReplay" because the ma command just grabs everything:
---Build RestReplay is put into your menu on a line by itself.
Use separating labels help to organize and document groups in one list. Consider using the space feature, with the
d s command, for working on other servers, or organizing by projects.
###Add ~/zanzibar (expanded) to your directory list
d -a ~/zanzibar
###Add ~/zanzibar (NOT expanded) to your directory list
d -a '~/zanzibar'
###Add $JAVA_HOME (NOT expanded) to your directory list
d -a '$JAVA_HOME'
###Add $JAVA_HOME (expanded) to your directory list
d -a $JAVA_HOME
###Choose directory 2 from your directory list
###Add . (expanded using `pwd`) to your directory list
d -a .
foo in current directory (expanded using
pwd/foo) to your directory list
d -a foo
###Add /var/log (full path, unexpanded) to your directory list
d -a /var/log
###Add a frequently used Maven (mvn) command to the menu and use the menu to run it.
The command is
mvn -DskipTests -o install and we are adding the whole thing using the
mvn is a popular build tool. You can see where it begins to run with the line "[INFO] Scanning for projects...
###Re-run that command without looking at the menu, now that you know the number
You could also run the command in your shell, then use the
ma command to capture the command to your command list in your current space. The ma command will take a command-line as its arguments. With no arguments, the ma command grabs the last item on your history. Note that you need to read the output of the ma command to see the index of the new command, in this case, the number
mvn -DskipTests -o install ma m 4