📜 ⬆️ ⬇️

ah - better than history

So it turns out that I spend enough time in the console (terminal), sometimes even more than I would like. Sometimes I even execute some commands there and carefully study their output. It often happens that one has to return to the conclusion of a team, but it is constantly lost: either the terminals are closed, the window is closed in tmux , then the conclusions of other teams have already been hammered and buried that very useful line.

In order to save the output of any utility, I, like many, used tee . It worked, but the constant bustle among the endless error.log , out.log , output.log , err.log log.log , lll.txt and so on, if not crazy, then annoying; instead of keeping some kind of order, it was constantly tempting to create a New Folder (1), where they could bury these same logs, periodically backing up the cemeteries: the order implied some sort of systematization, and in the midst of work I didn’t want to remember what to call my file.

Then I wrote ah , a tiny utility that greatly greatly improved my life.

ah was supposed to be a small addition to the history built-in command, which is in almost every shell; however, ah can only work with two: zsh (because I use it myself) and bash (because it is used by almost everyone who does not use zsh). This is by no means a substitute for history; rather, it is an addition to it. ah, basically, can do 4 things: show history, save the output of streams of commands, bind it to the number in the history, and show on demand. In addition, there is still such a trifle as bookmarks (any record from the history can be given a name).
')

Saving command output


ah can keep the combined output of the command, and she catalogs herself. In the simplest case, it suffices to do this:

 ➜ ah t -- find ./app -name "*.go" -type f ./app/historyentries/get_commands.go ./app/historyentries/parser.go ./app/historyentries/keeper.go ./app/historyentries/history_entry.go ./app/historyentries/history_processor.go ./app/environments/environments.go ./app/utils/re.go ./app/utils/logging.go ./app/utils/synchronized_writer.go ./app/utils/exec.go ./app/utils/utils.go ./app/commands/bookmark.go ./app/commands/remove_bookmarks.go ./app/commands/gc.go ./app/commands/list_trace.go ./app/commands/tee.go ./app/commands/execute.go ./app/commands/show.go ./app/commands/list_bookmarks.go ./app/slices/slices.go 


The output is saved (and combined with both stdout and stderr), and can be queried later. What is the difference from, say, tee? With tee, you can also write like

 ➜ find ./app -name "*.go" -type f |& tee output.log 


In fact, these commands are not equivalent. The fact is that for tee we redirect stderr to stdout, thereby losing the possibility of filtering them after tee. ah preserves this separation. In other words, we can write

 ➜ ah t -- find ./app -name "*.go" -type f > /dev/null 


And get on the screen only the output stderr. And what will save ah? It will keep both streams. And the return code. Yes, ah ends with the same code with which the previous command worked. Ah also works fine with ssh, even if you run ncurses applications there. If necessary, there is support for pseudo-TTY and the ability to run in a real interactive shell.

History show



 ➜ ah s 10 ... !10109 (02.11.14 18:05:14) nvim main.go !10110 (02.11.14 21:48:12) * ah t -- find ./app -name "*.go" -type f 


Yes, ah can show the contents of your HISTFILE and knows about HISTTIMEFORMAT . Guess why there are exclamation marks next to the number. But what does the star mean before ah t... ? That means ah stores the output of this command. You can view the output using the l subcommand.

 ➜ ah l 10110 ./app/historyentries/get_commands.go ./app/historyentries/parser.go ./app/historyentries/keeper.go ./app/historyentries/history_entry.go ./app/historyentries/history_processor.go ./app/environments/environments.go ./app/utils/re.go ./app/utils/logging.go ./app/utils/synchronized_writer.go ./app/utils/exec.go ./app/utils/utils.go ./app/commands/bookmark.go ./app/commands/remove_bookmarks.go ./app/commands/gc.go ./app/commands/list_trace.go ./app/commands/tee.go ./app/commands/execute.go ./app/commands/show.go ./app/commands/list_bookmarks.go ./app/slices/slices.go 


By the way, 10 in ah s 10 means literally "show the last 10 teams". At the same time, the slice syntax is supported (1: 1 as in Python): ah s 10 20 will show all commands from 11 to 20, ah s 10 _20 - from 11 to 20 from the end ( _ , but not - ). You can also search for regular expressions + there is a primitive fuzzy matching.

In addition, you can make bookmarks with the b subcommand, flip through them with lb , delete them with rb , clean old outputs with gt , but these are trifles.

I hope that someone else will live easier.

So there.
github.com/9seconds/ah

Source: https://habr.com/ru/post/242207/


All Articles