The command line. You either love it or hate it, but if you do anything with a Unix-like system you are going to have to use it eventually. You might find marker — a system billed as a “command palette for the terminal” — a useful program to install. We couldn’t decide if it was like command history on steroids or more of a bookmark system. In a way, it is a little of both.
Your history rolls off eventually and also contains a lot of small commands (although you can use the HISTIGNORE variable to ignore particular commands). With marker, you save specific commands and they stay saved. There are no extra commands nor do the ones you save ever roll off.
Of course, you could just make a shell script or an alias if that’s all there was to it. Marker lets you add a description to the command and then you can search through the commands and the descriptions using a fuzzy incremental search. In addition, you can put placeholders into your command lines that are easily replaced. There are some built-in commands to get you started and the same bookmarks will work in bash and zsh, if you use both.
Installing Marker
Marker is a standalone project which you can install from its Github repo. Installation is easy and doesn’t require root. However, you still have to add a line to your shell initialization file, although it does give you instructions after the install. However, since the default keybindings may not work for you, you might want to just manually source it at first until you are happy with it. Then make the changes to your initialization file. In other words, you might want to wait before issuing the last two commands.
git clone --depth=1 https://github.com/pindexis/marker ~/.marker && ~/.marker/install.py cp ~/.bashrc ~/.bashrc_backup echo '[[ -s "$HOME/.local/share/marker/marker.sh" ]] && source "$HOME/.local/share/marker/marker.sh"' >> ~/.bashrc
Depending on your Linux distro there may be a gotcha that you also need to workaround. If typing part of a command and hitting CTRL-Space throws the error bash: bash_execute_unix_command: cannot find keymap for command
you’ve encountered a known bug. Solved it by editing ~/.marker/bin/marker.sh
according to these instructions. In fact, many of the keybindings may have problems on some systems. It is easier to just issue a “source” command in a shell to activate marker for that shell until you are sure you want to use it all the time:
source ~/.local/share/marker/marker.sh
Then if you get stuck, you can just exit that shell and open another one to recover. Once you are satisfied with your set up, you can follow the instructions to make the change to your .bashrc. Of course, you can always recover by copying .bashrc_backup to .bashrc if you followed the instructions above.
How to Use Marker
Take Marker for a spin by using it to search through your command history. If you’re accustomed to using CTRL-R to reverse search you’ll find this handy. By default you can type part of a command and hit CTRL-Space to search commands. Instead of hitting the keystroke repeatedly and seeing one line at a time (as with reverse search) you get a nice color coded list to select from!
When reusing commands you usually need to backtrack to the input and output files and change them for your needs, Marker will let you do this with CTRL-T. Each time you press it the cursor will move to the next placeholder — shown in double curly brackets — removing the placeholder automatically so you can just begin typing.
You also can write your own commands along with placeholders and use CTRL-K to bookmark them. This is where Marker gets much more powerful than reverse searching.
You can see a demo above, which shows off how the placeholder (like {{url}} in the example) scheme works. By default, the keys are Control+Space, Control+K, and Control+T, but those interfere with other bindings on my system, so I changed them in the script to Alt-., Alt-M, and Alt-P (more on that later). You can also override them by setting environment variables before you source the script ~/.marker/marker.sh.
Problems
You can control everything with the marker command instead of keystrokes. However, it is sometimes difficult to pick items. For example, I never got the “marker update” command to work. You can remove commands with “marker remove.”
The only significant problem I found was that there are a lot of built-in rules and many of them are rules I would not use. However, there’s no easy way to delete them. I’m sure I can go find where they live in the code and nuke them, of course, but it would be nice if you could delete them just like your own rules.
Here’s a tip: The code loads the files ~/.marker/tldr/common.txt and one other file that is OS-specific (e.g., linux.txt). By editing those files you can alter the default rules easily. Better still, copy what you want to ~/.local/share/marker/user_commands.txt and then move the old files out of the way so the defaults you want are there and you can change them or remove them.
I mentioned before the keystroke settings are not good for users that use emacs-style keybindings. There isn’t much documentation but at the top of marker.sh the script sets the three keys from the environment and provides default values. That’s where I changed the bindings. Obviously, you could set the environment variables, too. Here’s the code in question (with my changes):
# default key bindings marker_key_mark="${MARKER_KEY_MARK:-\em}" marker_key_get="${MARKER_KEY_GET:-\e.}" marker_key_next_placeholder="${MARKER_KEY_NEXT_PLACEHOLDER:-\ep}"
The key names are what bind takes, which is poorly documented in general. The easiest way to figure it out is to do a “bind -P” and look how other keys work. In general, you can use Control keys like \C-t or keys with the \e prefix (typically Alt) as I did above. What documentation there is about this is in the bash manual under builtins.
In Practice
If you use the shell infrequently or you deal with super complex command lines this might be useful. We covered some other enhancements in an earlier installment of Linux Fu. By the way, if you add a lot of things to your bash startup and have more than one computer, you might enjoy my solution for using Git to manage and replicate your bash files.
Reminds me of good old 4DOS, the command.com alternative that featured a lot of unix-like command line trickery. Those were the days…
You may find this interesting, I put it on all my Windows machines:
https://mridgers.github.io/clink/
I likey. I often find myself scrolling back or searching through hundreds of commands to avoid typing that one long one again.
Thank you Mr. Williams.
Try control-r, reverse history search in bash and most similar shells.
Or `history | grep X` or `history | less` if you can’t remember precisely what you’re looking for
Also try installing fzf, it is like ctrl-r on steroids!
That was the subject of a previous Linux Fu.
Very *much* this. If bash+readline is your shell (which is almost 100% sure), CTRL-R (reverse search history) is it.
Those proposing history | grep (I used that back then, when my shell was called Korn) didn’t even try CTRL-R. It rocks:
– it doesn’t pollute your history with unnecessary “history | grep foo”
– it is an *incremental* reverse search: start typing characters and the
hits become more and more specific the longer your substring is
Usually I reach my target with three to four keystrokes.
And, oh — because it is libreadline, it will work as well with PostgreSQL’s client (psql), with R and with whatnot other interactive tools.
The real use case of this tool isn’t search as much as providing searchable aliases with meaningful descriptions. So if you are trying ot remember the command line you used a year ago to renew your SSL certs, you can find it even though it is long gone from your history.
I use vi as EDITOR, so I got search, and history|grep for week old stuff, but each terminal generates its own history and I use a lot of terminals.. So, I still think this might be better.
You can arrange for all your shells to feed one history — which some people like (I do) and some don’t. This is the history part of my bash startup:
# History Options
# Don’t put duplicate lines in the history.
export HISTCONTROL=”ignoredups:ignorespace”
# Ignore some controlling instructions
export HISTIGNORE=”[ ]*:&:bg:fg:exit”
shopt -s histappend
export PROMPT_COMMAND=”history -a; history -n; $PROMPT_COMMAND”
You should write about bash-it. It adds so much useful configurations for bash, and it’s a great way to install things in your bash rc.
I’ve started using a Jupyter notebook for repeated bash commands. It’s nice that you can put multiple commands in a cell, the out is saved and it’s easy to jump around between cells.
If you want to get rid of the list from tldr, change line 61 in ~/.marker/marker/core.py from
commands = command.load(get_user_marks_path()) + command.load(get_tldr_os_marks_path()) + command.load(get_t ldr_common_marks_path())
to
commands = command.load(get_user_marks_path())
Made me think about this:
https://github.com/nvbn/thefuck/blob/master/README.md
That’s hilarious, i have to try that. Now where’s the CoC of that project? :P
That drawing, it brought me here, even though the article series is interesting too.
Man, i really wish i had 10% of that talent. Can’t even draw anywhere near acceptable car, and yes i want to draw cars (mine and others’).
When I was a teen, the magazine CARtoons had a monthly “How to Draw a” feature.
Oh…
they resurrected…
https://cartoonsmag.com/
Oh nice, thanks for the tip. Might come in handy.
HISTIGNORE
alone is worth the price of reading this entire article! Thanks, Al.The traditional way to “solve” the same problem that marker does is with
alias
or just by writing a small script for each. Sure, you have to remember the names of the scripts, but you can call your “get hackaday” scriptget_hackaday
and you don’t lose much. Tab completion (see Al’s excellent article if you want to get fancy) and you’re done.Fuzzy search and a “bookmarks” file sound kinda cool though.
Pass: it’s not difficult to learn the command line, it just takes time. There are no real shortcuts in life.