See Also
Referenced By
The man page hstr(1) is an alias of hh(1).
|
Home | Switchboard | Unix Administration | Red Hat | TCP/IP Networks | Neoliberalism | Toxic Managers |
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and bastardization of classic Unix |
"Those who cannot remember the past are condemned to repeat it." George Santayana (1863-1952) |
|
Extracted from Professor Nikolai Bezroukov unpublished lecture notes.
Copyright 2010-2021, Dr. Nikolai Bezroukov. This is a fragment of the copyrighted unpublished work. All rights reserved.
Famous quote "Those who cannot remember the past are condemned to repeat it" has pretty literal meaning when you are using Unix shell in interactive mode :-). All modern shells have some mechanism of working with the history of commands that was originally introduced in C-shell. The ability to reuse command history is one of the signs of qualified Unix administrators: they typically rarely retype commands, preferring to retrieve them from history. This is safer and faster.
ATTENTION: In order to force bash to write lines in history on exit you need to put the line
shopt -s histappend
into your .bash_profile or a similar file (e.g. .profile) that executes for interactive sessions only. Without this option bash behaviour is simply stupid and is a source of a lot of grief. If you use multiple shell sessions and GNU screen, then situation is even more complex. In such cases it makes sense to write the history manually using the command history -a (Append the new history lines (history lines entered since the beginning of the current Bash session) to the different history files or history -n (Append the history lines not already read from the history file to the current history list. These are lines appended to the history file since the beginning of the current Bash session. )
This is typical problem if you use screen, or tmux.
You can also specify unique history files in your .bash_profile.
TIP:
If you use multiple shell sessions, you can also set or append the
history -a
command to thePROMPT_COMMAND
parameter, which contains commands that are executed before each new command prompt. To do this correctly, we need to do a bit of a hack. We need to append to the history file immediately withhistory -a
, clear the current history in our session withhistory -c
, and then read the history file that we've appended to, back into our session history withhistory -r
.
export PROMPT_COMMAND="history -n; history -c; history -r; $PROMPT_COMMAND"Bash history command can list all or part of the history file. It is only available in interactive sessions: it is disabled within scripts and you need to process history file is you need to get some commands from it. To retrieve history history command are usually used. Bash history implementation shows history file and memory buffer with recent commands. So the result of execution of history command is not the same as cat ~/.bash_history (if default name of history is used). It is the same if and only if you issue history -a command just before it.
History file is stored in a regular flat file one command per line and this file can be read and processed with standard Unix tools too, but by read by history command. For example grep. If you use data stamps then bash history is stored two line per commadn (with the first line being data stamp, and you can filter data stamps using egrep -v '^#'. For example,
cat ~/.bash_history | egrep -v '^#' | tail -100Bash provides an additional (and rather important in enterprise environment where there are multiple cooks in tthe kitchen) opportunity to timestamp history command.
The location of the history file is defined by the value of the environment variable HISTFILE. Its redirection from default location is somewhat tricky business as BASH is buggy in this respect. For example if you redirect root history to your user directory in recent versions of bash you lose the ability to view history with history command although file will be written correctly.
Bash history implementation is outdated and is not suitable
for multiple session, multiple users and maintaining the history of visited directoriesShell approach to keeping history on commands in a file writing to the file directly now looks outdated. It is not well suited for environment when a user works form multiple terminals. Or to the environment where there are multiple sysadmins on the server and you need a prefix that specifies who exactly issues particular command. You need something similar to syslog daemon to deal with this situation.
Also some important features like timestamp in bash were added as an after thought and not well integrated.
Moreover the "universal" shell commands history concept is open to review. Users and, especially, sysadmins, can benefit from some more specialized histories such as history of opened files and visited directires. Especially important is maintaining the history of visited directories.
Bash is unable to provide such slices of command history. You can do it using grep or Perl but there are no any built-in features that provide those or similar capabilities.
If you alias cd command to pushd then directory stack will be your proxy for history of visited directories. You also can write history of visited directories yourself by integrating
echo $PWD > ~/.dir_historyor similar command into your PROMPT_COMMAND function. Bash provides an environment variable called PROMPT_COMMAND. The contents of this variable is viewed as the name of the file that will be executed as a regular shell script just before Bash displays the prompt.
That means that there are several different avenues of making command history more useful:
Despite the fact that the cd command is a bash built-in, bash does not maintain separate history of visited directories.
The way to accomplish this created you private list of favorite directories and then populate the stack fro this list and keep it "as it" until you add of remove a directory from this list:
/bin/rm ~/.fav; dirs -c; cat ~/fav.lst | xargs -rn 1 echo pushd -n >> ~/.fav; . ~/.fav; dirs -v
To make this operation more convenient you can create function or and alias from this rather complex command line:
alias fav='/bin/rm ~/.fav; dirs -c; cat ~/fav.lst | xargs -rn 1 echo pushd -n >> ~/.fav; . ~/.fav 1>/dev/null; dirs -v'
After you can define function (for example go) which switch to the N directory from the top of your stack. For example:
function jmp { cd `dirs -l +$1` }
In other words the idea is to use dirs -l -v command to list content of the static stack containing your directory favorites. If the directory is in you list you can cd to the selected by typing its number. Generally you can avoid using popd at all. In this arrangements this is a useless command.
To populate the directory you can use command history (if you do not delete from it cd commands) but the problem with this solution is that in command history directories are seldom typed with absolute path. Instead the additions to the list of favorites can done via bash PROMPT_COMMAND string which specifies function executed each time you press Enter key and submit command for execution. For example in the function which is called via bash PROMPT_COMMAND setting you can have the following statement:
if [[ "x$PWD" != "x$PREVPWD" ]]: then echo $PWD >> ~/.dir_history } export PREVPWD=$PWD
You can be more adventurous and provide a single command which first dynamically created the list of favorite directories and then asks for the the number in this list of the directory to which you want to go:
# Nikolai Bezroukov, 2018 function go { cat ~/fav_static.lst > ~/fav.lst sort ~/.dir_history | uniq -c | sort -rn | cut -c 9- | head -7 >> ~/fav.lst # most frequent tail -5 ~/.dir_history >> ~/fav.lst # last used /bin/rm ~/.fav; dirs -c; cat ~/fav.lst | xargs -rn 1 echo pushd -n >> ~/.fav; . ~/.fav 1>/dev/null; dirs -v -l if (( $# > 0 )); then mydir=`dirs -l +$1` cd $mydir else echo -n 'Select the directory number in favorites: ' read target if [[ $target =~ \-[0-9]+ ]]; then echo $target let target=13+$target mydir=`dirs -l +$target` cd $mydir elif [[ target =~ [0-9]+ ]]; then echo +$target mydir=`dirs -l +$target` cd $mydir else echo ERROR: wrong target $target fi fi }
In the very simple implementation above the list of favorite directories is a composite consisting of three parts:
One advantage of this implementation is that the list of favorites is stired inthe array use by push/dirs commands and is availble with any of those commands too for example via function jmp descibed above
function jmp { cd `dirs -l +$1` }
Of course this implementation can be enhanced, but even in this primitive form it is really useful if you regularly deals with the deeply nested directories. I created it for working with genomic files.
Of course, you can move updates of the directories and creation of the .fav file for sourcing into your environment to cron (in this case the only thing you need in go function is to source .fav), but modern servers are so fast that those operation are instant anyway
Using shell or Perl (or any other scripting language that comfortable to you) you can write various useful postprocessors that provide relevant slices of history. For example, to see which commands you type most often and convert some of them into aliases you can use:
cut -f1 -d" " .bash_history | sort | uniq -c | sort -nr | head -12
After analyzing the list you can can create a set of directories favorites using aliases staring with a special letter, for example the letter "2":
alias 2log='cd /var/log' alias 2netconf='cd /etc/sysconfig/networking'
Modem implementations of file managers like you can find in various OFMs, such as mc, have those capabilities built-in. That means that you can use screen with the second screen being OFM file manager and use this second screen for navigating.
Synchronizing of directories between screens can be accomplished within PROMPT_COMMAND function, if you export a variable then represents the current directory from mc. For example, FAR maintains both history of opened files and the history of visited directories.
For files and directories OFMs usually have ways to organize permanent list of frequently used items similar to favorites in browsers.
Bash saves all the commands entered from your terminal device to a history file. But devil is detail and you need to use proper option or you will lose part of the history when closing bash session.
In order to force bash to write lines in history on exit you need to put the line
shopt -s histappend
into your .bash_profile or a similar file (e.g. .profile) that executes for interactive sessions only. Without this option bash behaviour is simply stupid and is a source of a lot of grief. If you use multiple shell sessions, then write the history manually using the command history -a
If you use multiple shell sessions, you need to write the history manually to preserver it using the command history -w
Default location of the history file is ~/.bash_history. It can be overwritten using HISTFILE variable. But again this capability is very buggy, if you try to do it for root history file. If the HISTFILE variable is not set or specified, or if the location specified cannot be written, the default name is used.
Actually this file should be treated not as a flat file but as a database. Generally history file should be append-only. That prevents mishaps when it is accidentally truncated. This can be accomplished by issuing the following command:
chattr +a ~joeuser/.bash_history
Control of the behavior of the command history is provided jointly by bash and the readline library. In addition to classic veriable ($HISTFILE) Bash provides four other variables that control what information is written to history( $HISTTIMEFORMAT, $HISTSIZE, $HISTCONTROL and $HISTIGNORE):
export HISTTIMEFORMAT='%F %T '
For example:
HISTCONTROL="erasedups:ignoreboth"
export HISTIGNORE="&:pwd:chpasswd:ls:ls \-l:ls -la:ll:cd:cd \-:cd /:cd .."
export HISTIGNORE="?? " ignores any 2 letter command.
History can also be browsed using arrow commands, but more efficient way is to use Ctrl-R for anything but previous half-dozen of commands. Ctrl-R mechanism provides search in history:
There are two ways to three ways of searching history of commands: linear, incremental and with grep.
You can grep last 100 or more commands in history for the commands you want, for example:
history 100 | grep '^cd'
function hs { egrep -v '^#' $HISTFILE | egrep "$1" }
In Suse there is also an interesting possibility to use page-up/page-down commands in searching: At a prompt type one or more characters then use Page Up/Page Down to scroll through all commands that started with these character
(Page-up-Page-down keys and shell history):
On Sat, 5 May 2001, Joost van der Lugt wrote:
Hi all,
I've been looking into this for a little bit and am unable to find an answer. This is a feature AFAIK only implemented by SuSE:
At a prompt type one or more characters then use Page Up/Page Down to scroll through all commands that started with these characters.
So typing:cdwould then give a 'scrollable' list of anything that started with cd simply hit enter when you reach the command you were looking for.
I know Ctrl-r and am familiar with ! but they are not as nice, and really not the same. Would anybody have a clue as to how this could be implemented?
I don't think it is shell dependent, so I don't think it's a bash option but I could very well be wrong.
(Tried the dotfile generator, but don't see anything there)
The option is _really_ addictive therefore my post:)
Thanks,
--
Cheers,
Joost van der Lugt
Most Unix shells including bash have some interesting extensions of the command history called bang commands. They allow you not only quickly retrieve several most recent commands but also reuse parts of previous command (or any command within history). Their role now is diminished as they are difficult to remember, and many of those manipulation can be done by retrieving the command from history and using keyboard and mouse to modify it. Still several of them retain their usefulness.
I think you need to know just three major bang commands (!!, !$, !1). It's actually difficult to remember more than that as their usage is pretty infrequent. Both !! (previous command -- usually in the idiom sudo !! and !$ (the last operand of the previous command) are extremely useful.
More convoluted bang operations are often simpler to perform just listing history and selecting the necessary substring using the mouse. but sometimes you do not have mouse capability (for example, in some trainings courses which is paranoid about intellectual property)
Replacement can also sometimes be very useful, when the reperecement string is deep inside previous command and you can't just erase tail and type the necessary replacement string. Here is one, not very convincing but simple example from Stupid Bash tricks- History, reusing arguments, files and directories, functions, and more - Enable Sysadmin
Let's say I run the following command:
$> sudo systemctl status sshd
Bash tells me the sshd service is not running, so the next thing I want to do is start the service. I had checked its status with my previous command. That command was saved in
history
, so I can reference it. I simply run:
$> !!:s/status/start/ sudo systemctl start sshd
The above expression has the following content:
- !! - repeat the last command from history
- :s/status/start/ - substitute status with start
The result is that the sshd service is started.
Next, I increase the default HISTSIZE value from 500 to 5000 by using the following command:
$> echo “HISTSIZE=5000” >> ~/.bashrc && source ~/.bashrc
What if I want to display the last three commands in my history? I enter:
$> history 3 1002 ls 1003 tail audit.log 1004 history 3
Bang commands are remnant of the era when typewriters were used as terminals but they proved to be used in CRT world too. There are way too many bang command to remember them all. But several most common cases should in the arsenal of any sysadmin, who respects himself. Because for various reason mouse some day might not be available. also some of those command are quicker then using mouse. I would outline seven most important usage cases:
There are a couple of useful idioms:
!tail:p
For hardcore system which despise mouse we will provide more complete overview of capabilities of band command. And as we mentioned before even for regular admin who use mouse there are cases when make sense to retrieve the previous commands arguments using so called word designators or bang arguments. We listed some above but there might be more for you and you can discover them analising the capabilities listed below.
Generally a colon (:) separates the event designator and the word designator, but it can be omitted, if the word designator begins with $, %, ^, *, or - . As well for for command line arguments from 1 to 9 ($1-$9)
If you want the word to be selected from the previous command line, the second ! is not required. For example, !!:12 and !:12 both refer to the 12-th word on the previous command. Moreover for arguments 1-9 you can omit the comons altotheres using !1-!9 notation.
You can address the necessary argument by using words, lines count from the last and search strings
Note: Escape sequence \! produces command history
number in bash prompts
- ls -l !cd:$ # $ point to the the last argument.
Here is a more compete reference:
Shell history issues became more complex, if there are multiple administrators on a particular server.
One of the ways to solve this problem is use sudo, but the problem is that the actions of individual admins now are reflected in this provate history and there is no "common" history to browse.
The same problem exists for a solution when .bash_profile assign individual .profile_sysadmin_id after switching to root that allows to individualize and relocate your history file.
So it is reasonable to assume that you need to write some scripts running from cron to create "merged" history, history in which commands are sorted using timestamps and prefixed by individual sysadmin IDs.
Another problem is that usage of screen and tmux is common and unless you put history -a in bash prompt function you never is sure that history of a particular sysdmin is complete and that some command did not dissper when the session is over or are hidden within particular screen session memory buffer.
Different people learn different patterns of work with shell, so the set of features one adopts is usually quite idiosyncratic. For example, I seldom use internal search of command history in the shell and prefer to use external history search via grep (I created a special, quite sophisticated function for that)
Drastic equipment changes during 45 years of Unix development creates problems within the idea of "pure" command line shell itself (with first features design to teletypes). This long and convoluted history of development of shell that includes several forks (tcsh, zsh, ksh93) naturally led to the situation when there are just too many features to learn in Unix shells. The idea of borrowing the best from each other work only so far. We need something better especially in multiple sysadmin environment, but it is unclear what ;-)
One alternative is to use orthodox file manager as a visual shell (for example midnight commander), but while improviding visiblity of filesystem it does nto solve other probes inherent in command line environment, for example "shared history" problem that I mentioned above.
Also if there way too many features, the features that you do not use often, you forget pretty soon, even if you wrote a web page about them ;-). Each time I edit this page I wonder how I manage forget so much about the shell history and why I use so few of the capabilities I myself describe on this page.
But there is a reason in it: intellectual capacities of humans are limited and Unix taxes them to the fullest expect. It is a classic example of OS that is too complex for "normal humans" to use. So creating a tiny subset is a natural defensive reaction against all this complexity. Many of the features that were essentials of classic teletype now are much less so when you have work from window GUI using emulator like Putty of Teraterm and mouse is supported in both environments.
But there is a fundamental feature that you should never forget: the less you type, the less mistakes you make. See Sysadmin Horror Stories about what can happen if you accidentally mistype some command. So maximizing reuse of "destructive" as well as other command is a legitimate goal for any sysadmin. In other words sysadmin should regularly consut his own command history to avoid blunders.
Maximal reuse of history should be the goal not because it make your work easier (after certain, minimal, let's say 20% mastery of features it does not speed up your work much), but because the more often you use history capability in shell the better is your "situational awareness is". Again another mean of increasing the situational awareness is to use OFM like Midnight Commander.
And that means that if you use history there are less chances that you in a hurry or because you is being tied commit some horrible blunder and then face SNAFU recovering from which might take a day or two and might cost you your job.
So diligently try I relearn useful methods of reusing the history and then, as usual, forget them in a couple of months. And this cycle looks like an infinite loop. In this sense the famous quote "Those who cannot remember the past are condemned to repeat it" has a different, more menacing meaning: Bash does suffer from Creeping featurism:
1. Describes a systematic tendency to load more chrome and features onto systems at the expense of whatever elegance they may have possessed when originally designed. See also feeping creaturism. "You know, the main problem with BSD Unix has always been creeping featurism."
2. More generally, the tendency for anything complicated to become even more complicated because people keep saying "Gee, it would be even better if it had this feature too". (See feature.) The result is usually a patchwork because it grew one ad-hoc step at a time, rather than being planned. Planning is a lot of work, but it's easy to add just one extra little feature to help someone ... and then another ... and another.... When creeping featurism gets out of hand, it's like a cancer.
Usually this term is used to describe computer programs, but it could also be said of the federal government, the IRS 1040 form, and new cars. A similar phenomenon sometimes afflicts conscious redesigns; see second-system effect. See also creeping elegance.
Here is more modern definition from Wikipedia:
Creeping featurism, or creeping featuritis, is a phrase used to describe software which over-emphasizes new features to the detriment of other design goals, such as simplicity, compactness, stability, or bug reduction. The term is often spoonerized as feeping creaturism, a term intended to bring the image of the encroaching features as small, seemingly benign animals that creep into a program, making their trademark noises and demanding their own space, soon taking over the entire project.
Creeping featurism is often accompanied by the mistaken belief that "one small feature" will add zero incremental cost to a project, where cost can be money, time, effort, or energy. A related term, feature creep, describes the tendency for a software project's completion to be delayed by the temptation to keep adding new features, without a specific goal.
Due to creeping featurism there are some built-in limits in productivity achievable with any old technology.
Often the way to raise productivity is to switch to a newer technology. There are several way to use bash more productively and less rely on retrieving old commands for enhancing your productivity. Among them:
If you are interested is using shell history you might be also interested in orthodox file managers that represent visual extension of the shell and as such greatly simplify the work of system administrator and tremendously raise the productivity. They are not perfect and not for all but to determine this you need to try them for a at least a couple of weeks.
For Linux the most popular orthodox file manager is probably Midnight commander. You can also always use two sessions: one with Orthodox file manager and another with regular shell and switch between two depending on the operation you need to perform. Browsing the tree and copy move operation are so much efficient in orthodox manager that you can feel real disappointment that you did not learn them after. Also browsing of the tree is simple and more visual. to get to the same directory in your second session export an environment viable if you are root or write file with the current directory and then source this file in other session.
So while each time I read this page with great interest, each time I try to remind myself that reusing the command that already work can prevent wiping out some important directory due to a typo; action that I already committed several time in the past :-). that's actually why using OFM file manager such as mc is a better way to work with Unix filesystem and no level of command line skills can compensate for missing GUI-style feedback they provide.
Screen can be combined with OFM (OFM manager can used in a separate screen). This is the environment I consider the most productive and strive to use as often as I can older versions of mc such as 4.6 which is "standard de facto" in many distributions has pretty primitive emulation of the terminal.
Another important way to improve your productivity is to learn to use GNU screen. It permit using multiple screens instead of switching to multiple directories and as such increase sysadmin productivity and lessens the number of mistakes.
The problem it solves is only peripherally related to the bash history, and can be described as following: many command that regular sysadmin types are connected with the necessity to work in two or more different directories. Having multiple screens (one for each directory) eliminate the necessity to type innumerous cd and ls commands. Screen also solves the problem of establishing your environment each time you login to particular server. and it preserves your session in case of accidental disconnects. In other words it is a must tool. I always pity "old style" Unix sysadmin that do this day after day. There are much more interesting ways to get RSI , for example playing computer games ;-)
I often use screen to create one session for each directory i use so I can simply switch to the other directory to perform some actions.
And the last, but not least was to enhance capabilities of bash history is to use programmable keyboards like Logitech keyboards. Recently Logitech discontinued G510s (18 macro keys) and most of other keyboards with two and three columns of functional (macro) keys) so you probably will be better off using other vendor; I just get used to Logitech) . Logitech keyboards with a single column with 6 or 9 functional keys are still available (for example G105 and G910). Cheaper keyboards with 6 programmable keys like CORSAIR K55 are plentiful with prices around $50. Actually 6 programmable keys are achievable on Microsoft keyboard 4000 with Microsoft Intellitype software.
The key problem is the quality of software that comes with the device. Logitech has the ability to program macros in LUA so it is still probably the most advanced option.
You can also use programmable keypads with a regular keyboard like (now discontinued) Logitech G13 gamepad, or more expensive but very similar RAZER ORBWEAVER CHROMA 30 Progammable Keys, or cheaper analogs like GameSir GK100, or Koolertron (compatible with Linux as it stored up to four profiles internally; has good reviews )
Here is one review of Razer gamepad from Amazon
5.0 out of 5 starsWonderful Digital Artist Tool! + SOME TIPS GETTING STARTED!March 24, 2017
Style: MechanicalVerified PurchaseI've had this nifty device for the past few months now, and I've finally decided to write a review. Note that I'll be updating my review as time goes on. Things might change, but my need of this (or a similar) device will certainly stick.
I didn't buy this to game with, though I'm looking forward to trying it out in the future. My goal for this purchase was to streamline my workflow, both for ergonomic and speed reasons. Working with a wacom + keyboard setup on my small desk was wreaking havoc on my shoulder, and because I do this professionally, I can't afford to miss work thanks to pinched nerves or sore arms. On top of that, I use a variety of programs throughout the day and I have trouble remembering all those shortcuts. I considered buying just an average keypad but I didn't much care for the idea that I'd have to switch up my shortcuts for everything, especially since I don't always work from home with my own setup.
Enter... the Orbweaver.
Comfort:As a woman with fairly small hands, I worried that this device would be too large for my needs; Now that I have it with me, I can see why some reviewers struggle with its size. My fingers don't quite reach the top row, and the bottom row can be a little on the awkward side to use. But because I'm not using this for gaming, I don't really see this as an issue. I've assigned my top row for things I don't typically need all that often (Save As, New Layer, etc) and it's worked out just fine.
As for comfort, I found the default configuration to be best for my needs. I've suffered no pain when using it (well, at the fault of the device anyway; more on that later) and I have yet to have the glue seepage issue arise (but I'm keeping an eye out for it). My thumb can reach the side buttons fine, though the SPACE button is out of reach; again, since I didn't buy this for gaming, it hasn't been much of a problem. I imagine if/when I do pick up a game, I can always reassign that button to one I can actually reach if need be.Functionality:
This thing has completely changed my workflow for the better. I'm using it for three apps right now (one at a time, so I can get used to my key layouts -- more on that later) and aside from some minor things here and there, it's been a dream to use.
I love that I can change the backlighting per profile. Esoteric Spine is set to red, PS is blue, CSP is currently lilac. I'm able to create countless profiles, each with a bunch of keymaps if I need it, and I've got half a dozen already! I do have some tips at the end of this review to help you create your own layouts, so check that out if you need it.Cons:
Yes, there are cons... as much as I love this device, I'm disappointed by a few things. These things are pretty much all SYNAPSE related. Synapse isn't a terrible app; I'm pretty okay with it, to be honest. Still, the hiccups and compatibility issues have given my Orbweaver quite the... uh, personality, and while I can find workarounds and fixes for some of its quirks, I'm still annoyed by its failings sometimes. Most of these things are issues that probably won't plague others, except for maybe the Mac version of Synapse: the biggest drawback I think we Mac users can all share in here is that one cannot change the color of the individual keys like advertised. Not a dealbreaker, not even really a big issue, but it's still an ability I would have liked to have.
Okay, now for the fun part my write-up... TIPS!When I first considered using the Orbweaver for my art needs, I combed the internet looking for recommended layouts and everything, and I found... NOTHING. I know, I know... a layout is a personal thing, based on one's own preferences; what works for one person isn't going to necessarily work for someone else. Still, I wish I at least had a list of suggestions I could go by.
TIPS ON GETTING STARTED:
(Now, I'm still working on my layouts. Don't be frustrated if you don't have the perfect setup right away; it takes time to figure out what feels right. But here is what I've picked up so far.)
- -My BIGGEST tip for you? Create an OFF mode! Disable every key for every keymap on this profile. Whenever you create a new profile, do so by duplicating this profile; that way, you have a clean slate every time you make a profile. This saves you SO much time, since Synapse doesn't seem to have a disable all option.
- -Whenever you start a new profile, give it a version number. (Example: Clip Studio Paint v1.) When you decide to make changes, duplicate that profile and make changes to your new version. That way, if you decide you prefer the old layout, you can just switch back. (I test out the new layout a few days and then delete the old one if I prefer the new one.)
- -I have found that 8, 12, and 14 are best used for my most frequent keys, since my fingers naturally rest on them. In Esoteric Spine, for example, I have these keys set to translate, rotate, and scale -- everything one needs to animate a character. I radiate out from these three keys by importance of other tools: copy/paste, play, save, etc. (Personal preference tip: 19 is great as undo! It's within quick reach, but you aren't going to accidentally hit it.)
- -Utilize multiple keymaps. You don't need to fill out one keymap completely before starting on the second! Like I said before, I assign my keys starting from where my fingers rest and radiating outward from that based on importance/frequency of use, but instead of sending certain shortcuts out of reach, I make them share keys with other shortcuts by using keymaps. (Brush is assigned to 8, for example, but so is brush size, because it's easier to remember for me. I can toggle between keymaps using left Alt, easy peasy!)
- -Assign harder to reach keys to things not so important/frequently used. (01 is assigned to Save for me. 03 is new layer. 05 is delete. etc.)
- -Either hunt down someone's lineart of the Orbweaver or make your own and print out a dozen or so copies to keep on hand. You can use these to visualize a layout plan and/or to put together a cheat sheet while you're learning to use your new keypad. Bust out some colored pencils and make a nice chart for yourself.
- -Seriously, you have to spend like... a week using the orbweaver and ONLY your orbweaver when it's time to make some art. Place your keyboard somewhere terribly inconvenient to you so you don't end up using it out of habit. You will be slow the first hour or so, but you'll be back to your usual speed by the end of the day; as you get used to it, you'll find yourself going MUCH master than before. Do this ONE PROFILE AT A TIME! You'll have a hard time remembering everything if you're switching between your profile for After Effects and your profile for Photoshop. Trust me, I tried. One program at a time, one profile at a time if you can.
Good luck! If you have any questions about how I use the orbweaver, just drop me a line in the comments.
This is especially convenient if you are using terminal emulator like Teraterm. Teraterm macros are also very helpful for automating repetitive tasks for example logging in to the server and establishing your environment (although the latter problem is solved by screen)
Dr. Nikolai Bezroukov
|
Switchboard | ||||
Latest | |||||
Past week | |||||
Past month |
Note: A highly recommended shell site is SHELLdorado by Heiner Steven. This is a really excellent site with the good coding practice section, some interesting example scripts and tips and tricks |
Jun 12, 2021 | anto.online
What if you needed to execute a specific command again, one which you used a while back? And you can't remember the first character, but you can remember you used the word "serve".
You can use the up key and keep on pressing up until you find your command. (That could take some time)
Or, you can enter CTRL + R and type few keywords you used in your last command. Linux will help locate your command, requiring you to press enter once you found your command. The example below shows how you can enter CTRL + R and then type "ser" to find the previously run "PHP artisan serve" command. For sure, this tip will help you speed up your command-line experience.
anto@odin:~$ (reverse-i-search)`ser': php artisan serveYou can also use the history command to output all the previously stored commands. The history command will give a list that is ordered in ascending relative to its execution.
softpanorama.org
Those shortcuts belong to the class of commands known as bang commands . Internet search for this term provides a wealth of additional information (which probably you do not need ;-), I will concentrate on just most common and potentially useful in the current command line environment bang commands. Of them !$ is probably the most useful and definitely is the most widely used. For many sysadmins it is the only bang command that is regularly used.
!! is the bang command that re-executes the last command . This command is used mainly as a shortcut sudo !! -- elevation of privileges after your command failed on your user account. For example:
fgrep 'kernel' /var/log/messages # it will fail due to unsufficient privileges, as /var/log directory is not readable by ordinary user sudo !! # now we re-execute the command with elevated privileges!$ puts into the current command line the last argument from previous command . For example:
mkdir -p /tmp/Bezroun/Workdir cd !$In this example the last command is equivalent to the command cd /tmp/Bezroun/Workdir. Please try this example. It is a pretty neat trick.NOTE: You can also work with individual arguments using numbers.
For example:
- !:1 is the previous command and its options
- !:2 is the first argument of the previous command
- !:3 is the second
- And so on
cp !:2 !:3 # picks up the first and the second argument from the previous commandFor this and other bang command capabilities, copying fragments of the previous command line using mouse is much more convenient, and you do not need to remember extra staff. After all, band commands were created before mouse was available, and most of them reflect the realities and needs of this bygone era. Still I met sysadmins that use this and some additional capabilities like !!:s^<old>^<new> (which replaces the string 'old' with the string 'new" and re-executes previous command) even now.The same is true for !* -- all arguments of the last command. I do not use them and have had troubles writing this part of this post, correcting it several times to make it right 4/0
Nowadays CTRL+R activates reverse search, which provides an easier way to navigate through your history then capabilities in the past provided by band commands.
linuxiac.com
The The'!'
symbol or operator in Linux can be used as Logical Negation operator as well as to fetch commands from history with tweaks or to run previously run command with modification. All the commands below have been checked explicitly in bash Shell. Though I have not checked but a major of these won't run in other shell. Here we go into the amazing and mysterious uses of'!'
symbol or operator in Linux commands.4. How to handle two or more arguments using (!)
Let's say I created a text file 1.txt on the Desktop.
$ touch /home/avi/Desktop/1.txtand then copy it to "˜ /home/avi/Downloads "˜ using complete path on either side with cp command.
$ cp /home/avi/Desktop/1.txt /home/avi/downloadsNow we have passed two arguments with cp command. First is "˜ /home/avi/Desktop/1.txt "˜ and second is "˜ /home/avi/Downloads "˜, lets handle them differently, just execute
echo [arguments]
to print both arguments differently.$ echo "1st Argument is : !^" $ echo "2nd Argument is : !cp:2"Note 1st argument can be printed as
"!^"
and rest of the arguments can be printed by executing"![Name_of_Command]:[Number_of_argument]"
.In the above example the first command was "˜ cp "˜ and 2nd argument was needed to print. Hence
5. Execute last command on the basis of keywords"!cp:2"
, if any command say xyz is run with 5 arguments and you need to get 4th argument, you may use"!xyz:4"
, and use it as you like. All the arguments can be accessed by"!*"
.We can execute the last executed command on the basis of keywords. We can understand it as follows:
$ ls /home > /dev/null [Command 1] $ ls -l /home/avi/Desktop > /dev/null [Command 2] $ ls -la /home/avi/Downloads > /dev/null [Command 3] $ ls -lA /usr/bin > /dev/null [Command 4]Here we have used same command (ls) but with different switches and for different folders. Moreover we have sent to output of each command to "˜ /dev/null "˜ as we are not going to deal with the output of the command also the console remains clean.
Now Execute last run command on the basis of keywords.
$ ! ls [Command 1] $ ! ls -l [Command 2] $ ! ls -la [Command 3] $ ! ls -lA [Command 4]Check the output and you will be astonished that you are running already executed commands just by
ls
keywords.6. The power of !! Operator
You can run/alter your last run command using
(!!)
. It will call the last run command with alter/tweak in the current command. Lets show you the scenarioLast day I run a one-liner script to get my private IP so I run,
$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/Then suddenly I figured out that I need to redirect the output of the above script to a file ip.txt , so what should I do? Should I retype the whole command again and redirect the output to a file? Well an easy solution is to use
UP
navigation key and add'> ip.txt'
to redirect the output to a file as.$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/ > ip.txtThanks to the life Savior
UP
navigation key here. Now consider the below condition, the next time I run below one-liner script.$ ifconfig | grep "inet addr:" | awk '{print $2}' | grep -v '127.0.0.1' | cut -f2 -d:As soon as I run script, the bash prompt returned an error with the message
"bash: ifconfig: command not found"
, It was not difficult for me to guess I run this command as user where it should be run as root.So what's the solution? It is difficult to login to root and then type the whole command again! Also ( UP Navigation Key ) in last example didn't came to rescue here. So? We need to call
"!!"
without quotes, which will call the last command for that user.$ su -c "!!" rootHere su is switch user which is root,
-c
is to run the specific command as the user and the most important part!!
will be replaced by command and last run command will be substituted here. Yeah! You need to provide root password.I make use of
!!
mostly in following scenarios,1. When I run apt-get command as normal user, I usually get an error saying you don't have permission to execute.
$ apt-get upgrade && apt-get dist-upgradeOpps error"¦don't worry execute below command to get it successful..
$ su -c !!Same way I do for,
$ service apache2 start or $ /etc/init.d/apache2 start or $ systemctl start apache2OOPS User not authorized to carry such task, so I run..
$ su -c 'service apache2 start' or $ su -c '/etc/init.d/apache2 start' or $ su -c 'systemctl start apache2'7. Run a command that affects all the file except ![FILE_NAME]
The
!
( Logical NOT ) can be used to run the command on all the files/extension except that is behind'!'
.A. Remove all the files from a directory except the one the name of which is 2.txt .
$ rm !(2.txt)B. Remove all the file type from the folder except the one the extension of which is "˜ pdf "˜.
$ $ rm !(*.pdf)... ... ...
- Edgar Allen May 19, 2015 at 10:30 pm
You might also mention !? It finds the last command with its' string argument. For example, if"¦
1013 grep tornado /usr/share/dict/words 1014 grep hurricane /usr/share/dict/words 1015 wc -l /usr/share/dict/wordsare all in the history then !?torn will grep for tornado again where !torn would search in vain for a command starting with torn.
And `wc !?torn?:2` works to select argument two from the command containing tornado and run `wc` on it.
- Stephen May 19, 2015 at 6:07 pm
I didn't see a mention of historical context in the article, so I'll give some here in the comments. This form of history command substitution originated with the C Shell (csh), created by Bill Joy for the BSD flavor of UNIX back in the late 70's. It was later carried into tcsh, and bash (Bourne-Again SHell).
Personally, I've always preferred the C-shell history substitution mechanism, and never really took to the fc command (that I first encountered in the Korne shell).
- suzy May 16, 2015 at 11:45 am
4th command. You can access it much simpler. There are actually regular expressions:
- ^ -- is at the begging expression
- $ -- is at the end expression
- :number -- any number parameter
Examples:
touch a.txt b.txt c.txt echo !^ ""> display first parameter echo !:1 ""> also display first parameter echo !:2 ""> display second parameter echo !:3 ""> display third parameter echo !$ ""> display last (in our case 3th) parameter echo !* ""> display all parameters- Tomasz Wiszkowski May 16, 2015 at 10:50 am
I think (5) works differently than you pointed out, and redirection to devnull hides it, but ZSh still prints the command.
When you invoke "! ls"¦", it always picks the last ls command you executed, just appends your switches at the end (after /dev/null).
One extra cool thing is the !# operator, which picks arguments from current line. Particularly good if you need to retype long path names you already typed in current line. Just say, for example
cp /some/long/path/to/file.abc !#:1And press tab. It's going to replace last argument with entire path and file name.
- Avishek Kumar May 18, 2015 at 11:37 pm
Tomasz,
For your first part of feedback: It doesn't pick the last command executed and just to prove this we have used 4 different switches for same command. ($ ! ls $ ! ls -l $ ! ls -la $ ! ls -lA ). Now you may check it by entering the keywords in any order and in each case it will output the same result.
As far as it is not working in ZSH as expected, i have already mentioned that it i have tested it on BASH and most of these won't work in other shell.
For the second part, what you mentioned is a HASH TAG in Linux Command Line and we have included it in one of our article. You may like to read it here: https://www.tecmint.com/linux-commandline-chat-server-and-remove-unwanted-packages/
Oct 02, 2019 | opensource.com
7 Bash history shortcuts you will actually use Save time on the command line with these essential Bash shortcuts. 02 Oct 2019 Ian 205 up 12 comments Image by : Opensource.com x Subscribe now
Most guides to Bash history shortcuts exhaustively list every single one available. The problem with that is I would use a shortcut once, then glaze over as I tried out all the possibilities. Then I'd move onto my working day and completely forget them, retaining only the well-known !! trick I learned when I first started using Bash.
So most of them were never committed to memory.
More on BashThis article outlines the shortcuts I actually use every day. It is based on some of the contents of my book, Learn Bash the hard way ; (you can read a preview of it to learn more).
- Bash cheat sheet
- An introduction to programming with Bash
- A sysadmin's guide to Bash scripting
- Latest Bash articles
When people see me use these shortcuts, they often ask me, "What did you do there!?" There's minimal effort or intelligence required, but to really learn them, I recommend using one each day for a week, then moving to the next one. It's worth taking your time to get them under your fingers, as the time you save will be significant in the long run.
1. The "last argument" one: !$2. The " n th argument" one: !:2If you only take one shortcut from this article, make it this one. It substitutes in the last argument of the last command into your line.
Consider this scenario:
$ mv / path / to / wrongfile / some / other / place
mv: cannot stat '/path/to/wrongfile' : No such file or directoryAch, I put the wrongfile filename in my command. I should have put rightfile instead.
You might decide to retype the last command and replace wrongfile with rightfile completely. Instead, you can type:
$ mv / path / to / rightfile ! $
mv / path / to / rightfile / some / other / placeand the command will work.
There are other ways to achieve the same thing in Bash with shortcuts, but this trick of reusing the last argument of the last command is one I use the most.
Ever done anything like this?
$ tar -cvf afolder afolder.tar
tar: failed to openLike many others, I get the arguments to tar (and ln ) wrong more often than I would like to admit.
tar_2x.pngWhen you mix up arguments like that, you can run:
$ ! : 0 ! : 1 ! : 3 ! : 2
tar -cvf afolder.tar afolderand your reputation will be saved.
The last command's items are zero-indexed and can be substituted in with the number after the !: .
Obviously, you can also use this to reuse specific arguments from the last command rather than all of them.
3. The "all the arguments": !*4. The "last but n " : !-2:$Imagine I run a command like:
$ grep '(ping|pong)' afileThe arguments are correct; however, I want to match ping or pong in a file, but I used grep rather than egrep .
I start typing egrep , but I don't want to retype the other arguments. So I can use the !:1$ shortcut to ask for all the arguments to the previous command from the second one (remember they're zero-indexed) to the last one (represented by the $ sign).
$ egrep ! : 1 -$
egrep '(ping|pong)' afile
pingYou don't need to pick 1-$ ; you can pick a subset like 1-2 or 3-9 (if you had that many arguments in the previous command).
The shortcuts above are great when I know immediately how to correct my last command, but often I run commands after the original one, which means that the last command is no longer the one I want to reference.
For example, using the mv example from before, if I follow up my mistake with an ls check of the folder's contents:
$ mv / path / to / wrongfile / some / other / place
mv: cannot stat '/path/to/wrongfile' : No such file or directory
$ ls / path / to /
rightfileI can no longer use the !$ shortcut.
In these cases, I can insert a - n : (where n is the number of commands to go back in the history) after the ! to grab the last argument from an older command:
$ mv / path / to / rightfile ! - 2 :$
mv / path / to / rightfile / some / other / placeAgain, once you learn it, you may be surprised at how often you need it.
5. The "get me the folder" one: !$:hThis one looks less promising on the face of it, but I use it dozens of times daily.
Imagine I run a command like this:
$ tar -cvf system.tar / etc / system
tar: / etc / system: Cannot stat: No such file or directory
tar: Error exit delayed from previous errors.The first thing I might want to do is go to the /etc folder to see what's in there and work out what I've done wrong.
I can do this at a stroke with:
$ cd ! $:h
cd / etcThis one says: "Get the last argument to the last command ( /etc/system ) and take off its last filename component, leaving only the /etc ."
6. The "the current line" one: !#:1For years, I occasionally wondered if I could reference an argument on the current line before finally looking it up and learning it. I wish I'd done so a long time ago. I most commonly use it to make backup files:
$ cp / path / to / some / file ! #:1.bak
cp / path / to / some / file / path / to / some / file.bakbut once under the fingers, it can be a very quick alternative to
7. The "search and replace" one: !!:gsThis one searches across the referenced command and replaces what's in the first two / characters with what's in the second two.
Say I want to tell the world that my s key does not work and outputs f instead:
$ echo my f key doef not work
my f key doef not workThen I realize that I was just hitting the f key by accident. To replace all the f s with s es, I can type:
$ !! :gs / f / s /
echo my s key does not work
my s key does not workIt doesn't work only on single characters; I can replace words or sentences, too:
$ !! :gs / does / did /
echo my s key did not work
my s key did not work Test them outJust to show you how these shortcuts can be combined, can you work out what these toenail clippings will output?
$ ping ! #:0:gs/i/o
$ vi / tmp /! : 0 .txt
$ ls ! $:h
$ cd ! - 2 :h
$ touch ! $! - 3 :$ !! ! $.txt
$ cat ! : 1 -$ ConclusionBash can be an elegant source of shortcuts for the day-to-day command-line user. While there are thousands of tips and tricks to learn, these are my favorites that I frequently put to use.
If you want to dive even deeper into all that Bash can teach you, pick up my book, Learn Bash the hard way or check out my online course, Master the Bash shell .
This article was originally posted on Ian's blog, Zwischenzugs.com , and is reused with permission.
Orr, August 25, 2019 at 10:39 pm
BTW – you inspired me to try and understand how to repeat the nth command entered on command line. For example I type 'ls' and then accidentally type 'clear'. !! will retype clear again but I wanted to retype ls instead using a shortcut.
Bash doesn't accept ':' so !:2 didn't work. !-2 did however, thank you!Dima August 26, 2019 at 7:40 am
Nice article! Just another one cool and often used command: i.e.: !vi opens the last vi command with their arguments.
cbarrick on 03 Oct 2019
Your "current line" example is too contrived. Your example is copying to a backup like this:
$ cp /path/to/some/file !#:1.bakBut a better way to write that is with filename generation:
$ cp /path/to/some/file{,.bak}That's not a history expansion though... I'm not sure I can come up with a good reason to use `!#:1`.
Darryl Martin August 26, 2019 at 4:41 pm
I seldom get anything out of these "bash commands you didn't know" articles, but you've got some great tips here. I'm writing several down and sticking them on my terminal for reference.
A couple additions I'm sure you know.
- I use "!*" for "all arguments". It doesn't have the flexibility of your approach but it's faster for my most common need.
- I recently started using Alt-. as a substitute for "!$" to get the last argument. It expands the argument on the line, allowing me to modify it if necessary.
Ricardo J. Barberis on 06 Oct 2019
The problem with bash's history shorcuts for me is... that I never had the need to learn them.
Provided that your shell is readline-enabled, I find it much easier to use the arrow keys and modifiers to navigate through history than type !:1 (or having to remeber what it means).
Examples:
Ctrl+R for a Reverse search
Ctrl+A to move to the begnining of the line (Home key also)
Ctrl+E to move to the End of the line (End key also)
Ctrl+K to Kill (delete) text from the cursor to the end of the line
Ctrl+U to kill text from the cursor to the beginning of the line
Alt+F to move Forward one word (Ctrl+Right arrow also)
Alt+B to move Backward one word (Ctrl+Left arrow also)
etc.YMMV of course.
Jul 01, 2020 | www.redhat.com
See also Bash bang commands- A must-know trick for the Linux command line - Enable Sysadmin
Let's say I run the following command:
$> sudo systemctl status sshdBash tells me the sshd service is not running, so the next thing I want to do is start the service. I had checked its status with my previous command. That command was saved in
history
, so I can reference it. I simply run:$> !!:s/status/start/ sudo systemctl start sshdThe above expression has the following content:
- !! - repeat the last command from history
- :s/status/start/ - substitute status with start
The result is that the sshd service is started.
Next, I increase the default HISTSIZE value from 500 to 5000 by using the following command:
$> echo "HISTSIZE=5000" >> ~/.bashrc && source ~/.bashrcWhat if I want to display the last three commands in my history? I enter:
$> history 3 1002 ls 1003 tail audit.log 1004 history 3I run
tail
onaudit.log
by referring to the history line number. In this case, I use line 1003:$> !1003 tail audit.logReference the last argument of the previous commandWhen I want to list directory contents for different directories, I may change between directories quite often. There is a nice trick you can use to refer to the last argument of the previous command. For example:
$> pwd /home/username/$> ls some/very/long/path/to/some/directory foo-file bar-file baz-fileIn the above example,
/some/very/long/path/to/some/directory
is the last argument of the previous command.If I want to
cd
(change directory) to that location, I enter something like this:$> cd $_ $> pwd /home/username/some/very/long/path/to/some/directoryNow simply use a dash character to go back to where I was:
$> cd - $> pwd /home/username/
Oct 23, 2019 | www.ostechnix.com
Let us take the following one-liner Linux command as an example.
$ find . -size +10M -type f -print0 | xargs -0 ls -Ssh | sort -zFor those wondering, the above command will find and list files bigger than 10 MB in the current directory and sort them by size. I admit that I couldn't remember this command. I guess some of you can't remember this command either. This is why we are going to apply a tag to such kind of commands.
To apply a tag, just type the command and add the comment ( i.e. tag) at the end of the command as shown below.
$ find . -size +10M -type f -print0 | xargs -0 ls -Ssh | sort -z #ListFilesBiggerThanXSizeHere, #ListFilesBiggerThanXSize is the tag name to the above command. Make sure you have given a space between the command and tag name. Also, please use the tag name as simple, short and clear as possible to easily remember it later. Otherwise, you may need another tool to recall the tags.
To run it again, simply use the tag name like below.
$ !? #ListFilesBiggerThanXSizeHere, the ! (Exclamation mark) and ? (Question mark) operators are used to fetch and run the command which we tagged earlier from the BASH history.
Aug 22, 2019 | www.ostechnix.com
Method 2 – Using history commandWe can use the history command's write option to print the history without numbers like below.
$ history -w /dev/stdoutMethod 3 – Using history and cut commandsOne such way is to use history and cut commands like below.
$ history | cut -c 8-
Nov 17, 2018 | dvorka.github.io
Configuration
Get most of HSTR by configuring it with:
hstr --show-configuration >> ~/.bashrcRun
hstr --show-configuration
to determine what will be appended to your Bash profile. Don't forget to source~/.bashrc
to apply changes.
For more configuration options details please refer to:
- bind HSTR to a keyboard shortcut
- Bash Emacs keymap (default)
- Bash Vim keymap
- zsh Emacs keymap (default)
- create
hh
alias forhstr
- het more colors
- choose default history view
- set filtering preferences
- configure commands blacklist
- disable confirm on delete
- tune verbosity
- history settings:
Check also configuration examples .
Binding HSTR to Keyboard ShortcutBash uses Emacs style keyboard shortcuts by default. There is also Vi mode. Find out how to bind HSTR to a keyboard shortcut based on the style you prefer below.
Check your active Bash keymap with:
bind -v | grep editing-mode bind -v | grep keymapTo determine character sequence emitted by a pressed key in terminal, type Ctrl-v and then press the key. Check your current bindings using:
bind -SBash Emacs Keymap (default)Bind HSTR to a Bash key e.g. to Ctrl-r :
bind '"\C-r": "\C-ahstr -- \C-j"'or Ctrl-Altr :
bind '"\e\C-r":"\C-ahstr -- \C-j"'or Ctrl-F12 :
bind '"\e[24;5~":"\C-ahstr -- \C-j"'Bind HSTR to Ctrl-r only if it is interactive shell:
if [[ $- =~ .*i.* ]]; then bind '"\C-r": "\C-a hstr -- \C-j"'; fiYou can bind also other HSTR commands like
--kill-last-command
:if [[ $- =~ .*i.* ]]; then bind '"\C-xk": "\C-a hstr -k \C-j"'; fiBash Vim KeymapBind HSTR to a Bash key e.g. to Ctrlr :
bind '"\C-r": "\e0ihstr -- \C-j"'Zsh Emacs KeymapBind HSTR to a
zsh
key e.g. to Ctrlr :bindkey -s "\C-r" "\eqhstr --\n"AliasIf you want to make running of
hstr
from command line even easier, then define alias in your~/.bashrc
:alias hh=hstrDon't forget to source
Colors~/.bashrc
to be able to to usehh
command.Let HSTR to use colors:
export HSTR_CONFIG=hicoloror ensure black and white mode:
export HSTR_CONFIG=monochromaticDefault History ViewTo show normal history by default (instead of metrics-based view, which is default) use:
export HSTR_CONFIG=raw-history-viewTo show favorite commands as default view use:
export HSTR_CONFIG=favorites-viewFilteringTo use regular expressions based matching:
export HSTR_CONFIG=regexp-matchingTo use substring based matching:
export HSTR_CONFIG=substring-matchingTo use keywords (substrings whose order doesn't matter) search matching (default):
export HSTR_CONFIG=keywords-matching
Make search case sensitive (insensitive by default):
export HSTR_CONFIG=case-sensitiveKeep duplicates in
raw-history-view
(duplicate commands are discarded by default):export HSTR_CONFIG=duplicatesStatic favoritesLast selected favorite command is put the head of favorite commands list by default. If you want to disable this behavior and make favorite commands list static, then use the following configuration:
export HSTR_CONFIG=static-favoritesSkip favorites commentsIf you don't want to show lines starting with
#
(comments) among favorites, then use the following configuration:export HSTR_CONFIG=skip-favorites-commentsBlacklistSkip commands when processing history i.e. make sure that these commands will not be shown in any view:
export HSTR_CONFIG=blacklistCommands to be stored in
~/.hstr_blacklist
file with trailing empty line. For instance:cd my-private-command ls llConfirm on DeleteDo not prompt for confirmation when deleting history items:
export HSTR_CONFIG=no-confirmVerbosityShow a message when deleting the last command from history:
export HSTR_CONFIG=verbose-killShow warnings:
export HSTR_CONFIG=warningShow debug messages:
export HSTR_CONFIG=debugBash History SettingsUse the following Bash settings to get most out of HSTR.
Increase the size of history maintained by BASH - variables defined below increase the number of history items and history file size (default value is 500):
export HISTFILESIZE=10000 export HISTSIZE=${HISTFILESIZE}Ensure syncing (flushing and reloading) of
.bash_history
with in-memory history:export PROMPT_COMMAND="history -a; history -n; ${PROMPT_COMMAND}"Force appending of in-memory history to
.bash_history
(instead of overwriting):shopt -s histappendUse leading space to hide commands from history:
export HISTCONTROL=ignorespaceSuitable for a sensitive information like passwords.
zsh History SettingsIf you use
zsh
, setHISTFILE
environment variable in~/.zshrc
:export HISTFILE=~/.zsh_historyExamplesMore colors with case sensitive search of history:
export HSTR_CONFIG=hicolor,case-sensitiveFavorite commands view in black and white with prompt at the bottom of the screen:
export HSTR_CONFIG=favorites-view,prompt-bottomKeywords based search in colors with debug mode verbosity:
export HSTR_CONFIG=keywords-matching,hicolor,debug
Nov 17, 2018 | www.mankier.com
hh -- easily view, navigate, sort and use your command history with shell history suggest box.
SynopsisDescription
hh [option] [arg1] [arg2]...
hstr [option] [arg1] [arg2]...hh uses shell history to provide suggest box like functionality for commands used in the past. By default it parses .bash-history file that is filtered as you type a command substring. Commands are not just filtered, but also ordered by a ranking algorithm that considers number of occurrences, length and timestamp. Favorite and frequently used commands can be bookmarked . In addition hh allows removal of commands from history - for instance with a typo or with a sensitive content.
OptionsKeys
- -h --help
- Show help
- -n --non-interactive
- Print filtered history on standard output and exit
- -f --favorites
- Show favorites view immediately
- -s --show-configuration
- Show configuration that can be added to ~/.bashrc
- -b --show-blacklist
- Show blacklist of commands to be filtered out before history processing
- -V --version
- Show version information
Environment Variables
- pattern
- Type to filter shell history.
- Ctrl-e
- Toggle regular expression and substring search.
- Ctrl-t
- Toggle case sensitive search.
- Ctrl-/ , Ctrl-7
- Rotate view of history as provided by Bash, ranked history ordered by the number of occurences/length/timestamp and favorites.
- Ctrl-f
- Add currently selected command to favorites.
- Ctrl-l
- Make search pattern lowercase or uppercase.
- Ctrl-r , UP arrow, DOWN arrow, Ctrl-n , Ctrl-p
- Navigate in the history list.
- TAB , RIGHT arrow
- Choose currently selected item for completion and let user to edit it on the command prompt.
- LEFT arrow
- Choose currently selected item for completion and let user to edit it in editor (fix command).
- ENTER
- Choose currently selected item for completion and execute it.
- DEL
- Remove currently selected item from the shell history.
- BACSKSPACE , Ctrl-h
- Delete last pattern character.
- Ctrl-u , Ctrl-w
- Delete pattern and search again.
- Ctrl-x
- Write changes to shell history and exit.
- Ctrl-g
- Exit with empty prompt.
hh defines the following environment variables:
Files
- HH_CONFIG
- Configuration options:
hicolor
Get more colors with this option (default is monochromatic).monochromatic
Ensure black and white view.prompt-bottom
Show prompt at the bottom of the screen (default is prompt at the top).regexp
Filter command history using regular expressions (substring match is default)substring
Filter command history using substring.keywords
Filter command history using keywords - item matches if contains all keywords in pattern in any order.casesensitive
Make history filtering case sensitive (it's case insensitive by default).rawhistory
Show normal history as a default view (metric-based view is shown otherwise).favorites
Show favorites as a default view (metric-based view is shown otherwise).duplicates
Show duplicates in rawhistory (duplicates are discarded by default).blacklist
Load list of commands to skip when processing history from ~/.hh_blacklist (built-in blacklist used otherwise).big-keys-skip
Skip big history entries i.e. very long lines (default).big-keys-floor
Use different sorting slot for big keys when building metrics-based view (big keys are skipped by default).big-keys-exit
Exit (fail) on presence of a big key in history (big keys are skipped by default).warning
Show warning.debug
Show debug information.Example:
export HH_CONFIG=hicolor,regexp,rawhistory- HH_PROMPT
- Change prompt string which is user@host$ by default.
Example:
export HH_PROMPT="$ "Bash Configuration
- ~/.hh_favorites
- Bookmarked favorite commands.
- ~/.hh_blacklist
- Command blacklist.
Optionally add the following lines to ~/.bashrc:
export HH_CONFIG=hicolor # get more colors shopt -s histappend # append new history items to .bash_history export HISTCONTROL=ignorespace # leading space hides commands from history export HISTFILESIZE=10000 # increase history file size (default is 500) export HISTSIZE=${HISTFILESIZE} # increase history size (default is 500) export PROMPT_COMMAND="history -a; history -n; ${PROMPT_COMMAND}" # if this is interactive shell, then bind hh to Ctrl-r (for Vi mode check doc) if [[ $- =~ .*i.* ]]; then bind '"\C-r": "\C-a hh -- \C-j"'; fiThe prompt command ensures synchronization of the history between BASH memory and history file.
ZSH ConfigurationOptionally add the following lines to ~/.zshrc:
export HISTFILE=~/.zsh_history # ensure history file visibility export HH_CONFIG=hicolor # get more colors bindkey -s "\C-r" "\eqhh\n" # bind hh to Ctrl-r (for Vi mode check doc, experiment with --)ExamplesAuthor
- hh git
- Start `hh` and show only history items containing 'git'.
- hh --non-interactive git
- Print history items containing 'git' to standard output and exit.
- hh --show-configuration >> ~/.bashrc
- Append default hh configuration to your Bash profile.
- hh --show-blacklist
- Show blacklist configured for history processing.
Written by Martin Dvorak <[email protected]>
BugsReport bugs to https://github.com/dvorka/hstr/issues
See Also
Referenced By
The man page hstr(1) is an alias of hh(1).
Oct 10, 2018 | www.cyberciti.biz
- Abhijeet Vaidya says: March 11, 2010 at 11:41 am End single quote is missing.
Correct command is:echo 'export HISTTIMEFORMAT="%d/%m/%y %T "' >> ~/.bash_profile- izaak says: March 12, 2010 at 11:06 am I would also add
$ echo 'export HISTSIZE=10000' >> ~/.bash_profile
It's really useful, I think.
- Dariusz says: March 12, 2010 at 2:31 pm you can add it to /etc/profile so it is available to all users. I also add:
# Make sure all terminals save history shopt -s histappend histreedit histverify shopt -s no_empty_cmd_completion # bash>=2.04 only# Whenever displaying the prompt, write the previous line to disk:
PROMPT_COMMAND='history -a'#Use GREP color features by default: This will highlight the matched words / regexes
export GREP_OPTIONS='–color=auto'
export GREP_COLOR='1;37;41′- Babar Haq says: March 15, 2010 at 6:25 am Good tip. We have multiple users connecting as root using ssh and running different commands. Is there a way to log the IP that command was run from?
Thanks in advance.
- Anthony says: August 21, 2014 at 9:01 pm Just for anyone who might still find this thread (like I did today):
export HISTTIMEFORMAT="%F %T : $(echo $SSH_CONNECTION | cut -d\ -f1) : "
will give you the time format, plus the IP address culled from the ssh_connection environment variable (thanks for pointing that out, Cadrian, I never knew about that before), all right there in your history output.
You could even add in $(whoami)@ right to get if you like (although if everyone's logging in with the root account that's not helpful).
- cadrian says: March 16, 2010 at 5:55 pm Yup, you can export one of this
env | grep SSH
SSH_CLIENT=192.168.78.22 42387 22
SSH_TTY=/dev/pts/0
SSH_CONNECTION=192.168.78.22 42387 192.168.36.76 22As their bash history filename
set |grep -i hist
HISTCONTROL=ignoreboth
HISTFILE=/home/cadrian/.bash_history
HISTFILESIZE=1000000000
HISTSIZE=10000000So in profile you can so something like HISTFILE=/root/.bash_history_$(echo $SSH_CONNECTION| cut -d\ -f1)
- TSI says: March 21, 2010 at 10:29 am bash 4 can syslog every command bat afaik, you have to recompile it (check file config-top.h). See the news file of bash: http://tiswww.case.edu/php/chet/bash/NEWS
If you want to safely export history of your luser, you can ssl-syslog them to a central syslog server.- Dinesh Jadhav says: November 12, 2010 at 11:00 am This is good command, It helps me a lot.
- Indie says: September 19, 2011 at 11:41 am You only need to use
export HISTTIMEFORMAT='%F %T 'in your .bash_profile
- lalit jain says: October 3, 2011 at 9:58 am -- show history with date & time
# HISTTIMEFORMAT='%c '
#history- Sohail says: January 13, 2012 at 7:05 am Hi
Nice trick but unfortunately, the commands which were executed in the past few days also are carrying the current day's (today's) timestamp.Please advice.
Regards
- Raymond says: March 15, 2012 at 9:05 am Hi Sohail,
Yes indeed that will be the behavior of the system since you have just enabled on that day the HISTTIMEFORMAT feature. In other words, the system recall or record the commands which were inputted prior enabling of this feature. Hope this answers your concern.
Thanks!
- Raymond says: March 15, 2012 at 9:08 am Hi Sohail,
Yes, that will be the behavior of the system since you have just enabled on that day the HISTTIMEFORMAT feature. In other words, the system can't recall or record the commands which were inputted prior enabling of this feature, thus it will just reflect on the printed output (upon execution of "history") the current day and time. Hope this answers your concern.
Thanks!
- Sohail says: February 24, 2012 at 6:45 am Hi
The command only lists the current date (Today) even for those commands which were executed on earlier days.
Any solutions ?
Regards
- nitiratna nikalje says: August 24, 2012 at 5:24 pm hi vivek.do u know any openings for freshers in linux field? I m doing rhce course from rajiv banergy. My samba,nfs-nis,dhcp,telnet,ftp,http,ssh,squid,cron,quota and system administration is over.iptables ,sendmail and dns is remaining.
-9029917299(Nitiratna)
- JMathew says: August 26, 2012 at 10:51 pm Hi,
Is there anyway to log username also along with the Command Which we typed
Thanks in Advance
- suresh says: May 22, 2013 at 1:42 pm How can i get full comman along with data and path as we het in history command.
- rajesh says: December 6, 2013 at 5:56 am Thanks it worked..
- Krishan says: February 7, 2014 at 6:18 am The command is not working properly. It is displaying the date and time of todays for all the commands where as I ran the some command three before.
How come it is displaying the today date
- PR says: April 29, 2014 at 5:18 pm Hi..
I want to collect the history of particular user everyday and want to send an email.I wrote below script.
for collecting everyday history by time shall i edit .profile file of that user
echo 'export HISTTIMEFORMAT="%d/%m/%y %T "' >> ~/.bash_profile
Script:#!/bin/bash #This script sends email of particular user history >/tmp/history if [ -s /tmp/history ] then mailx -s "history 29042014" </tmp/history fi rm /tmp/history #END OF THE SCRIPTCan any one suggest better way to collect particular user history for everyday
- lefty.crupps says: October 24, 2014 at 7:10 pm Love it, but using the ISO date format is always recommended (YYYY-MM-DD), just as every other sorted group goes from largest sorting (Year) to smallest sorting (day)
https://en.wikipedia.org/wiki/ISO_8601#Calendar_datesIn that case, myne looks like this:
echo 'export HISTTIMEFORMAT="%YY-%m-%d/ %T "' >> ~/.bashrcThanks for the tip!
- lefty.crupps says: October 24, 2014 at 7:11 pm please delete post 33, my command is messed up.
- lefty.crupps says: October 24, 2014 at 7:11 pm Love it, but using the ISO date format is always recommended (YYYY-MM-DD), just as every other sorted group goes from largest sorting (Year) to smallest sorting (day)
https://en.wikipedia.org/wiki/ISO_8601#Calendar_datesIn that case, myne looks like this:
echo ‘export HISTTIMEFORMAT=â€%Y-%m-%d %T “‘ >> ~/.bashrcThanks for the tip!
- Vanathu says: October 30, 2014 at 1:01 am its show only current date for all the command history
- lefty.crupps says: October 30, 2014 at 2:08 am it's marking all of your current history with today's date. Try checking again in a few days.
- tinu says: October 14, 2015 at 3:30 pm Hi All,
I Have enabled my history with the command given :
echo 'export HISTTIMEFORMAT="%d/%m/%y %T "' >> ~/.bash_profilei need to know how i can add the ip's also , from which the commands are fired to the system.
Jun 09, 2018 | opensource.com
Changing an executed command
history
also allows you to rerun a command with different syntax. For example, if I wanted to change my previous commandhistory | grep dnf
tohistory | grep ssh
, I can execute the following at the prompt:$ ^dnf^ssh^Removing history
history
will rerun the command, but replacednf
withssh
, and execute it.There may come a time that you want to remove some or all the commands in your history file. If you want to delete a particular command, enter
history -d <line number>
. To clear the entire contents of the history file, executehistory -c
.The history file is stored in a file that you can modify, as well. Bash shell users will find it in their Home directory as
Next steps.bash_history
.There are a number of other things that you can do with
history
:
- Set the size of your history buffer to a certain number of commands
- Record the date and time for each line in history
- Prevent certain commands from being recorded in history
For more information about the
history
command and other interesting things you can do with it, take a look at the GNU Bash Manual .
Feb 21, 2012 | sanctum.geek.nz
By default, the Bash shell keeps the history of your most recent session in the
.bash_history
file, and the commands you've issued in your current session are also available with ahistory
call. These defaults are useful for keeping track of what you've been up to in the shell on any given machine, but with disks much larger and faster than they were when Bash was designed, a little tweaking in your.bashrc
file can record history more permanently, consistently, and usefully. Append history instead of rewriting itYou should start by setting the
histappend
option, which will mean that when you close a session, your history will be appended to the.bash_history
file rather than overwriting what's in there.shopt -s histappendAllow a larger history fileThe default maximum number of commands saved into the
.bash_history
file is a rather meager 500. If you want to keep history further back than a few weeks or so, you may as well bump this up by explicitly setting$HISTSIZE
to a much larger number in your.bashrc
. We can do the same thing with the$HISTFILESIZE
variable.HISTFILESIZE=1000000 HISTSIZE=1000000The
man
page for Bash says thatHISTFILESIZE
can beunset
to stop truncation entirely, but unfortunately this doesn't work in.bashrc
files due to the order in which variables are set; it's therefore more straightforward to simply set it to a very large number.If you're on a machine with resource constraints, it might be a good idea to occasionally archive old
Don't store specific lines.bash_history
files to speed up login and reduce memory footprint.You can prevent commands that start with a space from going into history by setting
$HISTCONTROL
toignorespace
. You can also ignore duplicate commands, for example repeateddu
calls to watch a file grow, by addingignoredups
. There's a shorthand to set both inignoreboth
.HISTCONTROL=ignorebothYou might also want to remove the use of certain commands from your history, whether for privacy or readability reasons. This can be done with the
$HISTIGNORE
variable. It's common to use this to excludels
calls, job control builtins likebg
andfg
, and calls tohistory
itself:HISTIGNORE='ls:bg:fg:history'Record timestampsIf you set
$HISTTIMEFORMAT
to something useful, Bash will record the timestamp of each command in its history. In this variable you can specify the format in which you want this timestamp displayed when viewed withhistory
. I find the full date and time to be useful, because it can be sorted easily and works well with tools likecut
andawk
.HISTTIMEFORMAT='%F %T 'Use one command per lineTo make your
.bash_history
file a little easier to parse, you can force commands that you entered on more than one line to be adjusted to fit on only one with thecmdhist
option:shopt -s cmdhistStore history immediatelyBy default, Bash only records a session to the
.bash_history
file on disk when the session terminates. This means that if you crash or your session terminates improperly, you lose the history up to that point. You can fix this by recording each line of history as you issue it, through the$PROMPT_COMMAND
variable:PROMPT_COMMAND='history -a'
Aug 16, 2012 | sanctum.geek.nz
Setting the Bash option
histexpand
allows some convenient typing shortcuts using Bash history expansion . The option can be set with either of these:$ set -H $ set -o histexpandIt's likely that this option is already set for all interactive shells, as it's on by default. The manual,
man bash
, describes these features as follows:-H Enable ! style history substitution. This option is on by default when the shell is interactive.You may have come across this before, perhaps to your annoyance, in the following error message that comes up whenever
!
is used in a double-quoted string, or without being escaped with a backslash:$ echo "Hi, this is Tom!" bash: !": event not foundIf you don't want the feature and thereby make
!
into a normal character, it can be disabled with either of these:$ set +H $ set +o histexpandHistory expansion is actually a very old feature of shells, having been available in
csh
before Bash usage became common.This article is a good followup to Better Bash history , which among other things explains how to include dates and times in
Basic history expansionhistory
output, as these examples do.Perhaps the best known and most useful of these expansions is using
!!
to refer to the previous command. This allows repeating commands quickly, perhaps to monitor the progress of a long process, such as disk space being freed while deleting a large file:$ rm big_file & [1] 23608 $ du -sh . 3.9G . $ !! du -sh . 3.3G .It can also be useful to specify the full filesystem path to programs that aren't in your
$PATH
:$ hdparm -bash: hdparm: command not found $ /sbin/!! /sbin/hdparmIn each case, note that the command itself is printed as expanded, and then run to print the output on the following line.
History by absolute indexHowever,
!!
is actually a specific example of a more general form of history expansion. For example, you can supply the history item number of a specific command to repeat it, after looking it up withhistory
:$ history | grep expand 3951 2012-08-16 15:58:53 set -o histexpand $ !3951 set -o histexpandYou needn't enter the
!3951
on a line by itself; it can be included as any part of the command, for example to add a prefix likesudo
:$ sudo !3850If you include the escape string
History by relative index\!
as part of your Bash prompt , you can include the current command number in the prompt before the command, making repeating commands by index a lot easier as long as they're still visible on the screen.It's also possible to refer to commands relative to the current command. To subtitute the second-to-last command, we can type
!-2
. For example, to check whether truncating a file withsed
worked correctly:$ wc -l bigfile.txt 267 bigfile.txt $ printf '%s\n' '11,$d' w | ed -s bigfile.txt $ !-2 wc -l bigfile.txt 10 bigfile.txtThis works further back into history, with
Expanding for historical arguments!-3
,!-4
, and so on.In each of the above cases, we're substituting for the whole command line. There are also ways to get specific tokens, or words , from the command if we want that. To get the first argument of a particular command in the history, use the
!^
token:$ touch a.txt b.txt c.txt $ ls !^ ls a.txt a.txtTo get the last argument, add
!$
:$ touch a.txt b.txt c.txt $ ls !$ ls c.txt c.txtTo get all arguments (but not the command itself), use
!*
:$ touch a.txt b.txt c.txt $ ls !* ls a.txt b.txt c.txt a.txt b.txt c.txtThis last one is particularly handy when performing several operations on a group of files; we could run
du
andwc
over them to get their size and character count, and then perhaps decide to delete them based on the output:$ du a.txt b.txt c.txt 4164 a.txt 5184 b.txt 8356 c.txt $ wc !* wc a.txt b.txt c.txt 16689 94038 4250112 a.txt 20749 117100 5294592 b.txt 33190 188557 8539136 c.txt 70628 399695 18083840 total $ rm !* rm a.txt b.txt c.txtThese work not just for the preceding command in history, but also absolute and relative command numbers:
$ history 3 3989 2012-08-16 16:30:59 wc -l b.txt 3990 2012-08-16 16:31:05 du -sh c.txt 3991 2012-08-16 16:31:12 history 3 $ echo !3989^ echo -l -l $ echo !3990$ echo c.txt c.txt $ echo !-1* echo c.txt c.txtMore generally, you can use the syntax
!n:w
to refer to any specific argument in a history item by number. In this case, the first word, usually a command or builtin, is word0
:$ history | grep bash 4073 2012-08-16 20:24:53 man bash $ !4073:0 man What manual page do you want? $ !4073:1 bashYou can even select ranges of words by separating their indices with a hyphen:
$ history | grep apt-get 3663 2012-08-15 17:01:30 sudo apt-get install gnome $ !3663:0-1 purge !3663:3 sudo apt-get purge gnomeYou can include
Expanding history by string^
and$
as start and endpoints for these ranges, too.3*
is a shorthand for3-$
, meaning "all arguments from the third to the last."You can also refer to a previous command in the history that starts with a specific string with the syntax
!string
:$ !echo echo c.txt c.txt $ !history history 3 4011 2012-08-16 16:38:28 rm a.txt b.txt c.txt 4012 2012-08-16 16:42:48 echo c.txt 4013 2012-08-16 16:42:51 history 3If you want to match any part of the command line, not just the start, you can use
!?string?
:$ !?bash? man bashBe careful when using these, if you use them at all. By default it will run the most recent command matching the string immediately , with no prompting, so it might be a problem if it doesn't match the command you expect.
Checking history expansions before runningIf you're paranoid about this, Bash allows you to audit the command as expanded before you enter it, with the
histverify
option:$ shopt -s histverify $ !rm $ rm a.txt b.txt c.txtThis option works for any history expansion, and may be a good choice for more cautious administrators. It's a good thing to add to one's
.bashrc
if so.If you don't need this set all the time, but you do have reservations at some point about running a history command, you can arrange to print the command without running it by adding a
:p
suffix:$ !rm:p rm important-fileIn this instance, the command was expanded, but thankfully not actually run.
Substituting strings in history expansionsTo get really in-depth, you can also perform substitutions on arbitrary commands from the history with
!!:gs/pattern/replacement/
. This is getting pretty baroque even for Bash, but it's possible you may find it useful at some point:$ !!:gs/txt/mp3/ rm a.mp3 b.mp3 c.mp3If you only want to replace the first occurrence, you can omit the
g
:$ !!:s/txt/mp3/ rm a.mp3 b.txt c.txtStripping leading directories or trailing filesIf you want to chop a filename off a long argument to work with the directory, you can do this by adding an
:h
suffix, kind of like adirname
call in Perl:$ du -sh /home/tom/work/doc.txt $ cd !$:h cd /home/tom/workTo do the opposite, like a
basename
call in Perl, use:t
:$ ls /home/tom/work/doc.txt $ document=!$:t document=doc.txtStripping extensions or base namesA bit more esoteric, but still possibly useful; to strip a file's extension, use
:r
:$ vi /home/tom/work/doc.txt $ stripext=!$:r stripext=/home/tom/work/docTo do the opposite, to get only the extension, use
:e
:$ vi /home/tom/work/doc.txt $ extonly=!$:e extonly=.txtQuoting historyIf you're performing substitution not to execute a command or fragment but to use it as a string, it's likely you'll want to quote it. For example, if you've just found through experiment and trial and error an ideal
ffmpeg
command line to accomplish some task, you might want to save it for later use by writing it to a script:$ ffmpeg -f alsa -ac 2 -i hw:0,0 -f x11grab -r 30 -s 1600x900 \ > -i :0.0+1600,0 -acodec pcm_s16le -vcodec libx264 -preset ultrafast \ > -crf 0 -threads 0 "$(date +%Y%m%d%H%M%S)".mkvTo make sure all the escaping is done correctly, you can write the command into the file with the
:q
modifier:$ echo '#!/usr/bin/env bash' >ffmpeg.sh $ echo !ffmpeg:q >>ffmpeg.shIn this case, this will prevent Bash from executing the command expansion
"$(date ... )"
, instead writing it literally to the file as desired. If you build a lot of complex commands interactively that you later write to scripts once completed, this feature is really helpful and saves a lot of cutting and pasting.Thanks to commenter Mihai Maruseac for pointing out a bug in the examples.
Aug 29, 2017 | askubuntu.com
If you actually need the output of the
.bash_history
file , replacehistory
with
cat ~/.bash_history
in all of the commands below.If you actually want the commands without numbers in front, use this command instead of
history
:history | cut -d' ' -f 4-
Jul 29, 2017 | unix.stackexchange.com
Oli , asked Aug 26 '10 at 13:04
I consistently have more than one terminal open. Anywhere from two to ten, doing various bits and bobs. Now let's say I restart and open up another set of terminals. Some remember certain things, some forget.I want a history that:
- Remembers everything from every terminal
- Is instantly accessible from every terminal (eg if I
ls
in one, switch to another already-running terminal and then press up,ls
shows up)- Doesn't forget command if there are spaces at the front of the command.
Anything I can do to make bash work more like that?
Pablo R. , answered Aug 26 '10 at 14:37
# Avoid duplicates export HISTCONTROL=ignoredups:erasedups # When the shell exits, append to the history file instead of overwriting it shopt -s histappend # After each command, append to the history file and reread it export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"kch , answered Sep 19 '08 at 17:49
So, this is all my history-related.bashrc
thing:export HISTCONTROL=ignoredups:erasedups # no duplicate entries export HISTSIZE=100000 # big big history export HISTFILESIZE=100000 # big big history shopt -s histappend # append to history, don't overwrite it # Save and reload the history after each command finishes export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"Tested with bash 3.2.17 on Mac OS X 10.5, bash 4.1.7 on 10.6.
lesmana , answered Jun 16 '10 at 16:11
Here is my attempt at Bash session history sharing. This will enable history sharing between bash sessions in a way that the history counter does not get mixed up and history expansion like!number
will work (with some constraints).Using Bash version 4.1.5 under Ubuntu 10.04 LTS (Lucid Lynx).
HISTSIZE=9000 HISTFILESIZE=$HISTSIZE HISTCONTROL=ignorespace:ignoredups _bash_history_sync() { builtin history -a #1 HISTFILESIZE=$HISTSIZE #2 builtin history -c #3 builtin history -r #4 } history() { #5 _bash_history_sync builtin history "$@" } PROMPT_COMMAND=_bash_history_syncExplanation:More explanation:
- Append the just entered line to the
$HISTFILE
(default is.bash_history
). This will cause$HISTFILE
to grow by one line.- Setting the special variable
$HISTFILESIZE
to some value will cause Bash to truncate$HISTFILE
to be no longer than$HISTFILESIZE
lines by removing the oldest entries.- Clear the history of the running session. This will reduce the history counter by the amount of
$HISTSIZE
.- Read the contents of
$HISTFILE
and insert them in to the current running session history. this will raise the history counter by the amount of lines in$HISTFILE
. Note that the line count of$HISTFILE
is not necessarily$HISTFILESIZE
.- The
history()
function overrides the builtin history to make sure that the history is synchronised before it is displayed. This is necessary for the history expansion by number (more about this later).About the constraints of the history expansion:
- Step 1 ensures that the command from the current running session gets written to the global history file.
- Step 4 ensures that the commands from the other sessions gets read in to the current session history.
- Because step 4 will raise the history counter, we need to reduce the counter in some way. This is done in step 3.
- In step 3 the history counter is reduced by
$HISTSIZE
. In step 4 the history counter is raised by the number of lines in$HISTFILE
. In step 2 we make sure that the line count of$HISTFILE
is exactly$HISTSIZE
(this means that$HISTFILESIZE
must be the same as$HISTSIZE
).When using history expansion by number, you should always look up the number immediately before using it. That means no bash prompt display between looking up the number and using it. That usually means no enter and no ctrl+c.
Generally, once you have more than one Bash session, there is no guarantee whatsoever that a history expansion by number will retain its value between two Bash prompt displays. Because when
PROMPT_COMMAND
is executed the history from all other Bash sessions are integrated in the history of the current session. If any other bash session has a new command then the history numbers of the current session will be different.I find this constraint reasonable. I have to look the number up every time anyway because I can't remember arbitrary history numbers.
Usually I use the history expansion by number like this
$ history | grep something #note number $ !numberI recommend using the following Bash options.
## reedit a history substitution line if it failed shopt -s histreedit ## edit a recalled history line before executing shopt -s histverifyStrange bugs:Running the history command piped to anything will result that command to be listed in the history twice. For example:
$ history | head $ history | tail $ history | grep foo $ history | true $ history | falseAll will be listed in the history twice. I have no idea why.
Ideas for improvements:
- Modify the function
_bash_history_sync()
so it does not execute every time. For example it should not execute after aCTRL+C
on the prompt. I often useCTRL+C
to discard a long command line when I decide that I do not want to execute that line. Sometimes I have to useCTRL+C
to stop a Bash completion script.- Commands from the current session should always be the most recent in the history of the current session. This will also have the side effect that a given history number keeps its value for history entries from this session.
Maciej Piechotka , answered Aug 26 '10 at 13:20
I'm not aware of any way usingbash
. But it's one of the most popular features ofzsh
.
Personally I preferzsh
overbash
so I recommend trying it.Here's the part of my
.zshrc
that deals with history:SAVEHIST=10000 # Number of entries HISTSIZE=10000 HISTFILE=~/.zsh/history # File setopt APPEND_HISTORY # Don't erase history setopt EXTENDED_HISTORY # Add additional data to history like timestamp setopt INC_APPEND_HISTORY # Add immediately setopt HIST_FIND_NO_DUPS # Don't show duplicates in search setopt HIST_IGNORE_SPACE # Don't preserve spaces. You may want to turn it off setopt NO_HIST_BEEP # Don't beep setopt SHARE_HISTORY # Share history between session/terminalsChris Down , answered Nov 25 '11 at 15:46
To do this, you'll need to add two lines to your~/.bashrc
:shopt -s histappend PROMPT_COMMAND="history -a;history -c;history -r;" $PROMPT_COMMANDFrom
man bash
:If the histappend shell option is enabled (see the description of shopt under SHELL BUILTIN COMMANDS below), the lines are appended to the history file, otherwise the history file is over-written.
Schof , answered Sep 19 '08 at 19:38
You can edit your BASH prompt to run the "history -a" and "history -r" that Muerr suggested:savePS1=$PS1(in case you mess something up, which is almost guaranteed)
PS1=$savePS1`history -a;history -r`(note that these are back-ticks; they'll run history -a and history -r on every prompt. Since they don't output any text, your prompt will be unchanged.
Once you've got your PS1 variable set up the way you want, set it permanently it in your ~/.bashrc file.
If you want to go back to your original prompt while testing, do:
PS1=$savePS1I've done basic testing on this to ensure that it sort of works, but can't speak to any side-effects from running
history -a;history -r
on every prompt.pts , answered Mar 25 '11 at 17:40
If you need a bash or zsh history synchronizing solution which also solves the problem below, then see it at http://ptspts.blogspot.com/2011/03/how-to-automatically-synchronize-shell.htmlThe problem is the following: I have two shell windows A and B. In shell window A, I run
sleep 9999
, and (without waiting for the sleep to finish) in shell window B, I want to be able to seesleep 9999
in the bash history.The reason why most other solutions here won't solve this problem is that they are writing their history changes to the the history file using
PROMPT_COMMAND
orPS1
, both of which are executing too late, only after thesleep 9999
command has finished.jtimberman , answered Sep 19 '08 at 17:38
You can usehistory -a
to append the current session's history to the histfile, then usehistory -r
on the other terminals to read the histfile.jmanning2k , answered Aug 26 '10 at 13:59
I can offer a fix for that last one: make sure the env variable HISTCONTROL does not specify "ignorespace" (or "ignoreboth").But I feel your pain with multiple concurrent sessions. It simply isn't handled well in bash.
Toby , answered Nov 20 '14 at 14:53
Here's an alternative that I use. It's cumbersome but it addresses the issue that @axel_c mentioned where sometimes you may want to have a separate history instance in each terminal (one for make, one for monitoring, one for vim, etc).I keep a separate appended history file that I constantly update. I have the following mapped to a hotkey:
history | grep -v history >> ~/master_history.txtThis appends all history from the current terminal to a file called master_history.txt in your home dir.
I also have a separate hotkey to search through the master history file:
cat /home/toby/master_history.txt | grep -iI use cat | grep because it leaves the cursor at the end to enter my regex. A less ugly way to do this would be to add a couple of scripts to your path to accomplish these tasks, but hotkeys work for my purposes. I also periodically will pull history down from other hosts I've worked on and append that history to my master_history.txt file.
It's always nice to be able to quickly search and find that tricky regex you used or that weird perl one-liner you came up with 7 months ago.
Yarek T , answered Jul 23 '15 at 9:05
Right, So finally this annoyed me to find a decent solution:# Write history after each command _bash_history_append() { builtin history -a } PROMPT_COMMAND="_bash_history_append; $PROMPT_COMMAND"What this does is sort of amalgamation of what was said in this thread, except that I don't understand why would you reload the global history after every command. I very rarely care about what happens in other terminals, but I always run series of commands, say in one terminal:
make ls -lh target/*.foo scp target/artifact.foo vm:~/(Simplified example)
And in another:
pv ~/test.data | nc vm:5000 >> output less output mv output output.backup1No way I'd want the command to be shared
rouble , answered Apr 15 at 17:43
Here is my enhancement to @lesmana's answer . The main difference is that concurrent windows don't share history. This means you can keep working in your windows, without having context from other windows getting loaded into your current windows.If you explicitly type 'history', OR if you open a new window then you get the history from all previous windows.
Also, I use this strategy to archive every command ever typed on my machine.
# Consistent and forever bash history HISTSIZE=100000 HISTFILESIZE=$HISTSIZE HISTCONTROL=ignorespace:ignoredups _bash_history_sync() { builtin history -a #1 HISTFILESIZE=$HISTSIZE #2 } _bash_history_sync_and_reload() { builtin history -a #1 HISTFILESIZE=$HISTSIZE #2 builtin history -c #3 builtin history -r #4 } history() { #5 _bash_history_sync_and_reload builtin history "$@" } export HISTTIMEFORMAT="%y/%m/%d %H:%M:%S " PROMPT_COMMAND='history 1 >> ${HOME}/.bash_eternal_history' PROMPT_COMMAND=_bash_history_sync;$PROMPT_COMMANDsimotek , answered Jun 1 '14 at 6:02
I have written a script for setting a history file per session or task its based off the following.# write existing history to the old file history -a # set new historyfile export HISTFILE="$1" export HISET=$1 # touch the new file to make sure it exists touch $HISTFILE # load new history file history -r $HISTFILEIt doesn't necessary save every history command but it saves the ones that i care about and its easier to retrieve them then going through every command. My version also lists all history files and provides the ability to search through them all.
Full source: https://github.com/simotek/scripts-config/blob/master/hiset.sh
Litch , answered Aug 11 '15 at 0:15
I chose to put history in a file-per-tty, as multiple people can be working on the same server - separating each session's commands makes it easier to audit.# Convert /dev/nnn/X or /dev/nnnX to "nnnX" HISTSUFFIX=`tty | sed 's/\///g;s/^dev//g'` # History file is now .bash_history_pts0 HISTFILE=".bash_history_$HISTSUFFIX" HISTTIMEFORMAT="%y-%m-%d %H:%M:%S " HISTCONTROL=ignoredups:ignorespace shopt -s histappend HISTSIZE=1000 HISTFILESIZE=5000History now looks like:
user@host:~# test 123 user@host:~# test 5451 user@host:~# history 1 15-08-11 10:09:58 test 123 2 15-08-11 10:10:00 test 5451 3 15-08-11 10:10:02 historyWith the files looking like:
user@host:~# ls -la .bash* -rw------- 1 root root 4275 Aug 11 09:42 .bash_history_pts0 -rw------- 1 root root 75 Aug 11 09:49 .bash_history_pts1 -rw-r--r-- 1 root root 3120 Aug 11 10:09 .bashrcfstang , answered Sep 10 '16 at 19:30
Here I will point out one problem withexport PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"and
PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n"If you run source ~/.bashrc, the $PROMPT_COMMAND will be like
"history -a; history -c; history -r history -a; history -c; history -r"and
"history -a; history -n history -a; history -n"This repetition occurs each time you run 'source ~/.bashrc'. You can check PROMPT_COMMAND after each time you run 'source ~/.bashrc' by running 'echo $PROMPT_COMMAND'.
You could see some commands are apparently broken: "history -n history -a". But the good news is that it still works, because other parts still form a valid command sequence (Just involving some extra cost due to executing some commands repetitively. And not so clean.)
Personally I use the following simple version:
shopt -s histappend PROMPT_COMMAND="history -a; history -c; history -r"which has most of the functionalities while no such issue as mentioned above.
Another point to make is: there is really nothing magic . PROMPT_COMMAND is just a plain bash environment variable. The commands in it get executed before you get bash prompt (the $ sign). For example, your PROMPT_COMMAND is "echo 123", and you run "ls" in your terminal. The effect is like running "ls; echo 123".
$ PROMPT_COMMAND="echo 123"output (Just like running 'PROMPT_COMMAND="echo 123"; $PROMPT_COMMAND'):
123Run the following:
$ echo 3output:
3 123"history -a" is used to write the history commands in memory to ~/.bash_history
"history -c" is used to clear the history commands in memory
"history -r" is used to read history commands from ~/.bash_history to memory
See history command explanation here: http://ss64.com/bash/history.html
PS: As other users have pointed out, export is unnecessary. See: using export in .bashrc
Hopping Bunny , answered May 13 '15 at 4:48
Here is the snippet from my .bashrc and short explanations wherever needed:# The following line ensures that history logs screen commands as well shopt -s histappend # This line makes the history file to be rewritten and reread at each bash prompt PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n" # Have lots of history HISTSIZE=100000 # remember the last 100000 commands HISTFILESIZE=100000 # start truncating commands after 100000 lines HISTCONTROL=ignoreboth # ignoreboth is shorthand for ignorespace and ignoredupsThe HISTFILESIZE and HISTSIZE are personal preferences and you can change them as per your tastes.
Mulki , answered Jul 24 at 20:49
This works for ZSH############################################################################## # History Configuration for ZSH ############################################################################## HISTSIZE=10000 #How many lines of history to keep in memory HISTFILE=~/.zsh_history #Where to save history to disk SAVEHIST=10000 #Number of history entries to save to disk #HISTDUP=erase #Erase duplicates in the history file setopt appendhistory #Append history to the history file (no overwriting) setopt sharehistory #Share history across terminals setopt incappendhistory #Immediately append to the history file, not just when a term is killed
Jul 25, 2017 | eli.thegreenplace.net
June 11, 2013 at 19:27 Tags Linux , Software & Tools
Update (Jan 26, 2016): I posted a short update about my usage of persistent history.
For someone spending most of his time in front of a Linux terminal, history is very important. But traditional bash history has a number of limitations, especially when multiple terminals are involved (I sometimes have dozens open). Also it's not very good at preserving just the history you're interested in across reboots.
There are many approaches to improve the situation; here I want to discuss one I've been using very successfully in the past few months - a simple "persistent history" that keeps track of history across terminal instances, saving it into a dot-file in my home directory ( ~/.persistent_history ). All commands, from all terminal instances, are saved there, forever. I found this tremendously useful in my work - it saves me time almost every day.
Why does it go into a separate history and not the main one which is accessible by all the existing history manipulation tools? Because IMHO the latter is still worthwhile to be kept separate for the simple need of bringing up recent commands in a single terminal, without mixing up commands from other terminals. While the terminal is open, I want the press "Up" and get the previous command, even if I've executed a 1000 other commands in other terminal instances in the meantime.
Persistent history is very easy to set up. Here's the relevant portion of my ~/.bashrc :
log_bash_persistent_history() { [[ $(history 1) =~ ^\ *[0-9]+\ +([^\ ]+\ [^\ ]+)\ +(.*)$ ]] local date_part="${BASH_REMATCH[1]}" local command_part="${BASH_REMATCH[2]}" if [ "$command_part" != "$PERSISTENT_HISTORY_LAST" ] then echo $date_part "|" "$command_part" >> ~/.persistent_history export PERSISTENT_HISTORY_LAST="$command_part" fi } # Stuff to do on PROMPT_COMMAND run_on_prompt_command() { log_bash_persistent_history } PROMPT_COMMAND="run_on_prompt_command"The format of the history file created by this is:
2013-06-09 17:48:11 | cat ~/.persistent_history 2013-06-09 17:49:17 | vi /home/eliben/.bashrc 2013-06-09 17:49:23 | lsNote that an environment variable is used to avoid useless duplication (i.e. if I run ls twenty times in a row, it will only be recorded once).
OK, so we have ~/.persistent_history , how do we use it? First, I should say that it's not used very often, which kind of connects to the point I made earlier about separating it from the much higher-use regular command history. Sometimes I just look into the file with vi or tail , but mostly this alias does the trick for me:
alias phgrep='cat ~/.persistent_history|grep --color'The alias name mirrors another alias I've been using for ages:
alias hgrep='history|grep --color'Another tool for managing persistent history is a trimmer. I said earlier this file keeps the history "forever", which is a scary word - what if it grows too large? Well, first of all - worry not. At work my history file grew to about 2 MB after 3 months of heavy usage, and 2 MB is pretty small these days. Appending to the end of a file is very, very quick (I'm pretty sure it's a constant-time operation) so the size doesn't matter much. But trimming is easy:
tail -20000 ~/.persistent_history | tee ~/.persistent_historyTrims to the last 20000 lines. This should be sufficient for at least a couple of months of history, and your workflow should not really rely on more than that :-)
Finally, what's the use of having a tool like this without employing it to collect some useless statistics. Here's a histogram of the 15 most common commands I've used on my home machine's terminal over the past 3 months:
ls : 865 vi : 863 hg : 741 cd : 512 ll : 289 pss : 245 hst : 200 python : 168 make : 167 git : 148 time : 94 python3 : 88 ./python : 88 hpu : 82 cat : 80Some explanation: hst is an alias for hg st . hpu is an alias for hg pull -u . pss is my awesome pss tool , and is the reason why you don't see any calls to grep and find in the list. The proportion of Mercurial vs. git commands is likely to change in the very
history -a
to preserve history
from multiple terminals. This is a very neat trick !!!get=
Bash history handling with multiple terminals
The bash session that is saved is the one for the terminal that is closed the latest. If you want to save the commands for every session, you could use the trick explained here.
export PROMPT_COMMAND='history -a'To quote the manpage: "If set, the value is executed as a command prior to issuing each primary prompt."
So every time my command has finished, it appends the unwritten history item to
~/.bash
ATTENTION: If you use multiple shell sessions and do not use this trick, you need to write the history manually to preserver it using the command history -a
See also:
nickgeoghegan.net
One of the annoyances of Bash, is that searching through your history has no context. When did I last run that command? What commands were run at 3am, while on the lock?The following, single line, run in the shell, will provide date and time stamping for your Bash History the next time you login, or run bash.
echo 'export HISTTIMEFORMAT="%h/%d - %H:%M:%S "' >> ~/.bashrc
Okay, well say you didn't just run the sought-after command. You know you've used it within the past few days, but you don't want to scroll through what could be hundreds of commands to find it. Well, there are a couple of ways to do this, depending on how much you can remember about the history yourself...
- special knowledge
- If you know you haven't executed any commands with the same starting letter sequence since then, you can just use the built-in Bash history expansion command
!
followed by the first few letters of the command.- The unique string doesn't have to be at the start of the command. You can use the more flexible built-in Bash history expansion command
!?
followed by a unique string appearing anywhere in the command.- Both of these commands will immediately recall and execute the most recent matching command. Thus, it is usually not a good idea to use these methods with destructive commands like
rm
!- some knowledge
- If you aren't positively sure of what would happen if you were to use the
!
or!?
method, or if you need to search for something more unique in the command than the first few letters can provide, then you could use the history search feature.- Before you begin typing your command, type
ctrl-r
. This will put you into history search mode (actually, reverse incremental history search mode).- Now when you begin typing, the most recent command matching what you've typed so far will appear on the line with a cursor at the start of the match. (Try playing around with this feature; there are a few interesting behaviors in there.)
- When you've found what you're looking for, you have a couple of options. Just pressing Enter will immediately recall and execute the command.
ctrl-j
or Escape will retrieve the command, but allow you to continue editing. If you can't find what you're looking for or if you just change your mind, hitctrl-g
orctrl-c
to cancel.- vague memory
- If you really are uncertain of the history or if you know you could be searching back through many similar commands for one of particular interest, then you can use this more brute-force method.
- Type the following command to get a list of all related commands with their history numbers:
history | grep -i "<search string>"
- Once you've found the command you want, you can execute it specifically by its number using the following built-in history expansion command:
!<history number>
Remember: Once you've used one of these methods to recall and execute a command, that command is now the most recent command in your history. You can now just press the up arrow once to retrieve it again.
Okay, so now you can recall commands with relative ease. But we really haven't done anything special yet. We're just using the default behaviors and commands provided in Bash. The trick comes in configuring what gets put into your history!
A little-known trick (I've only seen one distro ship with this turned on by default) is that you can filter what gets stored in the command history. This is done merely by setting an environment variable,
$HISTIGNORE
.Just set the HISTIGNORE variable to a colon-delimited list of patterns which should be excluded. There's also the special pattern '&', which suppresses duplicate entries (very useful!).
Here's an example that suppresses duplicate commands, the simple invocation of '
ls
' without any arguments, and the shell built-insbg
,fg
, andexit
:
export HISTIGNORE="&:ls:[bf]g:exit"
Try it out. I think you'll like it.
Here's a neat trick, submitted by Robert Cymbala. If you include the expression "
[ \t]*
" in the HISTIGNORE string, you can suppress history recording at will for any given command just by starting with a space!
Another optional feature of Bash history filtering that isn't always enabled by default in distributions is
cmdhist
. This determines whether multi-line commands are stored in the history as a single command (on) or not (off; default). This makes it much easier to go back and edit multi-line commands.To enable this feature, you would type
shopt -s cmdhist
To disable this feature, you would type
shopt -u cmdhist
As you may have guessed, there are many options for Bash that can be toggled using the 'shopt' built-in. They are documented here.
I would like to keep track of what, when and where I've done something in the shell for the rest of my Linux life. It is a reasonable wish to have all of my activities logged, so in the future I could check what I did, how I did, and when I did it. Of cause it imposes some security hazard if you type in your password by mistake while working in the shell prompt, so you should be careful and have right permissions setup.This article is excerpt from its original page where you can see how it evolved ;-)
The first solution would be to set HISTSIZE to be very big, but then I don't know how well your bash would behave -- I believe it tries to keep them all in memory. But I want to have my bash fast and lightweighted! So it must be accomplished in another way.
Lets use a big file ~/.bash_history.archive (separate from HISTFILE=~/.bash_history). And then on exit from each bash session lets append new history lines to it. To accomplish that we need to remember how far in the history we were at the beginning of the session and at the end of session, so we could dump lines inbetween to our log file. The problem I've ran into is that it is impossible at the time of run of .bash{rc,_profile} to know status of history, thus I ended up scanning HISTFILE, thus I still can have some bugs because this way is unnatural.
To enable such historing you need merely to source a .bash_history from your ~/.bashrc. Optionally you can modify .inputrc to have shortcut to dump history without exiting shell. I provide source of the script directly in the article so it is available even if my website goes down (I hope it will not in the nearest future)
#!/bin/bash #-------------------------- =+- Shell script -+= -------------------------- # @file .bashrc_history.sh # @date Thu Mar 10 14:02:36 2005 # @brief # # CVS version control block - do not edit manually # $RCSfile: .bashrc_history,v $ # $Source: /home/cvs/yoh/.bashrc_history,v $ # # Created: Thu Mar 10 14:02:36 2005 # Commited: $Date: 2005/03/24 14:24:28 $ # Revision: $Revision: 1.7 $ # # Yaroslav Halchenko CS@UNM, CS@NJIT # web: http://www.onerussian.com & PSYCH@RUTGERS # e-mail: [email protected] ICQ#: 60653192 # # DESCRIPTION (NOTES): # A script to be sourced from .bashrc to provide ways to archive all the # actions in infinitely long history file. # # To use, just place # 'source .bashrc_history' in ~/.bashrc # # '$if Bash # # to exit through calling exit function which will archive the history # # next ones are optional: first is left for historical reasons # "\C-x\C-x": "exit\n" # "\C-x\C-w": "archive_history\n" # $endif' in ~/.inputrc # # Then whenever you close bash (exit,logout or exit by pressing Ctrl-D # or Ctrl-X twice you will have a piece of current history added to # ~/.bash_history.archive # # SOURCE: # http://www.onerussian.com/Linux/.files/.bashrc_history # # LICENSE: # Released under GNU Generic Public License. You should've received it with # your GNU/Linux system. If not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #-----------------\____________________________________/------------------ if [ "$PS1" ] ; then # interactive shell export \ CURBASHSTART=$(grep -v -e "^[ \t]*$" -e "^\s*#" $HISTFILE 2>/dev/null /dev/null) \ CURBASHDATE=$(date > $HISTORYOLD history $(($HISTCMD-$CURBASHSTART-1)) | sed -e 's/^[ ]*[0-9][0-9]* [ ]*//g' >> $HISTORYOLD CURBASHSTART=$(($HISTCMD-1)) fi } trap 'archive_history' EXIT fiP.S. There might be much better/safer way to reach the goal -- thus comments are very welcome
Task 4 Check command history for "string" but avoid running it
Print the first occurrence of string found in the history, but don't run it.
!string:p!string will search your command history and execute the first command that matches 'whatever'. If you don't feel safe doing this put :p on the end to print without executing. Recommended when running as superuser.
Task 5 delete a line of the history
Useful when you do an error and type a password as normal command.
Apply to bash
history -d < history number >Delete the entry with the < history number > from the command line history
Task 6 List of commands you use most often
useful in deciding what new alias to do or for the statistics.
Apply to bash and zsh
history | awk '{print $2}' | sort | uniq -c | sort -rn | headOutput:
53 aptitude 47 ip 40 ls 33 apt-get 26 cd 25 xrandr 24 man 17 history 15 rmmod 15 apt-cacheCheck Also the Bash history cheatsheet
by Vivek Gite · 16 comments
How do I display shell command history with date and time under UNIX or Linux operating systems?
If the HISTTIMEFORMAT is set, the time stamp information associated with each history entry is written to the history file, marked with the history comment character. Defining the environment variable as follows:
$ HISTTIMEFORMAT="%d/%m/%y %T "OR$ echo 'export HISTTIMEFORMAT="%d/%m/%y %T "' >> ~/.bash_profileWhere,%d - Day
%m - Month
%y - Year
%T - TimeTo see history type
$ historySample outputs:.... .. 986 11/03/10 04:31:36 memcached-tool 10.10.28.22:11211 stats 987 11/03/10 04:31:36 w 988 11/03/10 04:31:37 iostat 989 11/03/10 04:31:37 top 990 11/03/10 04:31:37 at 991 11/03/10 04:31:38 atop 992 11/03/10 04:31:40 collectl 993 11/03/10 04:31:41 grep CPU /proc/cpuinfo 994 11/03/10 04:31:45 vmstat 3 100 995 11/03/10 04:31:55 sar -W -f /var/log/sa/sa12 ....
- izaak 03.12.10 at 11:06 am
- I would also add
$ echo 'export HISTSIZE=10000' >> ~/.bash_profileIt's really useful, I think.
- 14 Dariusz 03.12.10 at 2:31 pm
- you can add it to /etc/profile so it is available to all users. I also add:
# Make sure all terminals save history
shopt -s histappend histreedit histverify shopt -s no_empty_cmd_completion # bash>=2.04 only# Whenever displaying the prompt, write the previous line to disk:
PROMPT_COMMAND='history -a'#Use GREP color features by default: This will highlight the matched words / regexes
export GREP_OPTIONS='-color=auto' export GREP_COLOR='1;37;41'- 15 Babar Haq 03.15.10 at 6:25 am
- Good tip. We have multiple users connecting as root using ssh and running different commands. Is there a way to log the IP that command was run from?
Thanks in advance.- 16 cadrian 03.16.10 at 5:55 pm
- Yup, you can export one of this:
env | grep SSH SSH_CLIENT=192.168.78.22 42387 22 SSH_TTY=/dev/pts/0 SSH_CONNECTION=192.168.78.22 42387 192.168.36.76 22As their bash history filename
set |grep -i hist HISTCONTROL=ignoreboth > HISTFILE=/home/cadrian/.bash_history HISTFILESIZE=1000000000 HISTSIZE=10000000So in profile you can so something like
HISTFILE=/root/.bash_history_$(echo $SSH_CONNECTION| cut -d\ -f1)
16 Jul 2008 | Deadman.org
Bash provides a couple of methods for searching the command history. Both are useful in different situations. The first method is to simply type history, find the number of the command you want and then type !N where "N" is the number of the command you'd like to execute. (:p works here too.) The other method is a tad more complex but also adds flexibilty.
^r (ctrl-r) followed by whatever you type will search the command history for that string.
The bonus here is that you're able to edit the command line you've searched for before you send it down the line. While the second method is more powerful, when doing some redundant task, it's much easier to remember !22 than it is to muck with ctrl-r type searches or even the arrow keys.
Bang dollar-sign
!$ is the "end" of the previous command. Consider the following example: We start by looking for a word in a file
grep -i joe /some/long/directory/structure/userlists/list-15if joe is in that userlist, we want to remove him from it. We can either fire up vi with that long directory tree as the argument, or as simply as
vi !$A word of caution: !$ expands to the end word of the previous command. What's a word? The bash man page calls a word "A sequence of characters considered as a single unit by the shell." If you haven't changed anything, chances are good that a word is a quoted string or a white-space delimited group of characters. What is a white-space delimited group of characters ? It's a group of characters that are separated from other characters by some form of white-space (which could be a tab, space, etc.) If you're in doubt, :p works here too.Another thing to keep in mind when using !$ is that if the previous command had no agruments, !$ will expand to the previous command rather than the most recent argument. This can be handy if, for example, you forget to type vi and you just type the filename. A simple vi !$ and you're in.
Similar to !$ is !*. !* is all of the arguments to the previous command rather than just the last one. As usual, this is useful in many situations. Here's a simple example:
vi cd /stuff
oops!
[exit vi, twice]
!*
Which bash expands to: cd /stuff
... ... ...
A few handy movement commands
Sometimes a mistake is noticed before the enter key is pressed. We've already talked about terminals that don't translate cursor-keys properly, so how do you fix a mistake? To make matters worse, sometimes the backspace key gets mapped to ^H or even worse something like ^[[~. Now how do you fix your mistake before hitting the enter key?
Once again, bash comes through for us. Here are some of the movement keystrokes that I use most often:
- ^w erase word
- ^u erase from here to beginning of the line (I use this ALL the time.)
- ^a move the cursor to the beginning of the line
- ^e move the curor to the end of the line
There are more of course, but those are the ones you simply can't live without. For those who don't know the ^N notation means ctrl+N, don't confuse it with hats mentioned above.
tab-tab
One of my favorite features of bash is tab-completion. Tab-completion works in a couple of ways, it can complete filenames in the current directory or in your $PATH. Like the !commands above, you just need to give bash enough of the filename to make it unique and hit the tab key -- bash will do the rest for you. Let's say you have a file in your home directory called ransom.note, consider the following:
mor[tab] ran[tab]Will expand to
more ransom.note
Let's say you also have a file named random in your home directory. ran above is no longer enough to be unique, but you're in luck. If you hit tab twice, bash will print the list of matching files to the screen so that you can see what you need to add to make your shortcut unique.
Send comments to Sam Rowe, deadman at deadman dot org.
July 03, 2006 | ,Linux.com
fc: Displays, Edits, and Reexecutes Commands
The fc (fix command) builtin enables you to display the history list and edit and reexecute previous commands. It provides many of the same capabilities as the command line editors.
When you call fc with the -l option, it displays commands from the history list. Without any arguments, fc -l lists the 16 most recent commands in a numbered list, with the oldest appearing first:
$ fc -l 1024 cd 1025 view calendar 1026 vim letter.adams01 1027 aspell -c letter.adams01 1028 vim letter.adams01 1029 lpr letter.adams01 1030 cd ../memos 1031 ls 1032 rm *0405 1033 fc -l 1034 cd 1035 whereis aspell 1036 man aspell 1037 cd /usr/share/doc/*aspell* 1038 pwd 1039 ls 1040 ls man-htmlThe fc builtin can take zero, one, or two arguments with the -l option. The arguments specify the part of the history list to be displayed:
fc -l [ first [ last ]]The fc builtin lists commands beginning with the most recent event that matches first. The argument can be an event number, the first few characters of the command line, or a negative number, which is taken to be the n th previous command. If you provide last , fc displays commands from the most recent event that matches first through the most recent event that matches last . The next command displays the history list from event 1030 through event 1035:
fc -l 1030 1035 1030 cd ../memos 1031 ls 1032 rm *0405 1033 fc -l 1034 cd 1035 whereis aspellThe following command lists the most recent event that begins with view through the most recent command line that begins with whereis:
$ fc -l view whereis 1025 view calendar 1026 vim letter.adams01 1027 aspell -c letter.adams01 1028 vim letter.adams01 1029 lpr letter.adams01 1030 cd ../memos 1031 ls 1032 rm *0405 1033 fc -l 1034 cd 1035 whereis aspellTo list a single command from the history list, use the same identifier for the first and second arguments. The following command lists event 1027:
$ fc -l 1027 1027 1027 aspell -c letter.adams01You can use fc to edit and reexecute previous commands.
fc [-e editor ] [ first [ last ]]When you call fc with the -e option followed by the name of an editor, fc calls the editor with event(s) in the Work buffer. Without first and last , fc defaults to the most recent command. The next example invokes the vi(m) editor to edit the most recent command:
$ fc -e viThe fc builtin uses the stand-alone vi(m) editor. If you set the FCEDIT variable, you do not need to use the -e option to specify an editor on the command line. Because the value of FCEDIT has been changed to /usr/bin/emacs and fc has no arguments, the following command edits the most recent command with the emacs editor:
$ export FCEDIT=/usr/bin/emacs $ fcIf you call it with a single argument, fc invokes the editor on the specified command. The following example starts the editor with event 21 in the Work buffer. When you exit from the editor, the shell executes the command:
$ fc 21Again you can identify commands with numbers or by specifying the first few characters of the command name. The following example calls the editor to work on events from the most recent event that begins with the letters vim through event 206:
$ fc vim 206When you execute an fc command, the shell executes whatever you leave in the editor buffer, possibly with unwanted results. If you decide you do not want to execute a command, delete everything from the buffer before you exit from the editor.
You can reexecute previous commands without going into an editor. If you call fc with the -s option, it skips the editing phase and reexecutes the command. The following example reexecutes event 1029:
$ fc -s 1029 lpr letter.adams01The next example reexecutes the previous command:
$ fc -sWhen you reexecute a command you can tell fc to substitute one string for another. The next example substitutes the string john for the string adams in event 1029 and executes the modified event:
$ fc -s adams=john 1029 lpr letter.john01Using an Exclamation Point (!) to Reference Events
The C Shell history mechanism uses an exclamation point to reference events, and is available under bash. It is frequently more cumbersome to use than fc but nevertheless has some useful features. For example, the !! command reexecutes the previous event, and the !$ token represents the last word on the previous command line.
You can reference an event by using its absolute event number, its relative event number, or the text it contains. All references to events, called event designators, begin with an exclamation point (!). One or more characters follow the exclamation point to specify an event.
You can put history events anywhere on a command line. To escape an exclamation point so that it is treated literally instead of as the start of a history event, precede it with a backslash (\) or enclose it within single quotation marks.
An event designator specifies a command in the history list.
Event designators
Designator Meaning ! Starts a history event unless followed immediately by SPACE, NEWLINE, =, or (. !! The previous command. !n Command number n in the history list. !-n The n th preceding command. !string The most recent command line that started with string . !?string[?] The most recent command that contained string . The last ? is optional. !# The current command (as you have it typed so far). !{event} The event is an event designator. The braces isolate event from the surrounding text. For example, !{-3}3 is the third most recently executed command followed by a 3. You can always reexecute the previous event by giving a !! command. In the following example, event 45 reexecutes event 44:
44 $ ls -l text -rw-rw-r-- 1 alex group 45 Apr 30 14:53 text 45 $ !! ls -l text -rw-rw-r-- 1 alex group 45 Apr 30 14:53 textThe !! command works whether or not your prompt displays an event number. As this example shows, when you use the history mechanism to reexecute an event, the shell displays the command it is reexecuting.
A number following an exclamation point refers to an event. If that event is in the history list, the shell executes it. Otherwise, the shell displays an error message. A negative number following an exclamation point references an event relative to the current event. For example, the command !-3 refers to the third preceding event. After you issue a command, the relative event number of a given event changes (event -3 becomes event -4). Both of the following commands reexecute event 44:
51 $ !44 ls -l text -rw-rw-r-- 1 alex group 45 Nov 30 14:53 text 52 $ !-8 ls -l text -rw-rw-r-- 1 alex group 45 Nov 30 14:53 textWhen a string of text follows an exclamation point, the shell searches for and executes the most recent event that began with that string. If you enclose the string between question marks, the shell executes the most recent event that contained that string. The final question mark is optional if a RETURN would immediately follow it.
68 $ history 10 59 ls -l text* 60 tail text5 61 cat text1 text5 > letter 62 vim letter 63 cat letter 64 cat memo 65 lpr memo 66 pine jenny 67 ls -l 68 history 69 $ !l ls -l ... 70 $ !lpr lpr memo 71 $ !?letter? cat letter ...Optional - Word Designators
A word designator specifies a word or series of words from an event.
Word designators
Designator Meaning n The n th word. Word 0 is normally the command name. ^ The first word (after the command name). $ The last word. m-n All words from word number m through word number n ; m defaults to 0 if you omit it (0- n ). n* All words from word number n through the last word. * All words except the command name. The same as 1*. % The word matched by the most recent ?string? search. The words are numbered starting with 0 (the first word on the line -- usually the command), continuing with 1 (the first word following the command), and going through n (the last word on the line).
To specify a particular word from a previous event, follow the event designator (such as !14) with a colon and the number of the word in the previous event. For example, !14:3 specifies the third word following the command from event 14. You can specify the first word following the command (word number 1) by using a caret (^) and the last word by using a dollar sign ($). You can specify a range of words by separating two word designators with a hyphen.
72 $ echo apple grape orange pear apple grape orange pear 73 $ echo !72:2 echo grape grape 74 $ echo !72:^ echo apple apple 75 $ !72:0 !72:$ echo pear pear 76 $ echo !72:2-4 echo grape orange pear grape orange pear 77 $ !72:0-$ echo apple grape orange pear apple grape orange pearAs the next example shows, !$ refers to the last word of the previous event. You can use this shorthand to edit, for example, a file you just displayed with cat:
$ cat report.718 ... $ vim !$ vim report.718 ...If an event contains a single command, the word numbers correspond to the argument numbers. If an event contains more than one command, this correspondence does not hold true for commands after the first. In the following example, event 78 contains two commands separated by a semicolon so that the shell executes them sequentially; the semicolon is word number 5.
78 $ !72 ; echo helen jenny barbara echo apple grape orange pear ; echo helen jenny barbara apple grape orange pear helen jenny barbara 79 $ echo !78:7 echo helen helen 80 $ echo !78:4-7 echo pear ; echo helen pear helenOn occasion you may want to change an aspect of an event you are reexecuting. Perhaps you entered a complex command line with a typo or incorrect pathname, or you want to specify a different argument. You can modify an event or a word of an event by putting one or more modifiers after the word designator, or after the event designator if there is no word designator. Each modifier must be preceded by a colon (:).
The substitute modifier is more complex than the other modifiers. The following example shows the substitute modifier correcting a typo in the previous event:
$ car /home/jenny/memo.0507 /home/alex/letter.0507 bash: car: command not found $ !!:s/car/cat cat /home/jenny/memo.0507 /home/alex/letter.0507 ...The substitute modifier has the following syntax:
[g]s/ old _/ new _/where old is the original string (not a regular expression), and new is the string that replaces old . The substitute modifier substitutes the first occurrence of old with new . Placing a g before the s (as in gs/old/new/) causes a global substitution, replacing all occurrences of old . The / is the delimiter in the examples, but you can use any character that is not in either old or new . The final delimiter is optional if a RETURN would immediately follow it. As with the vim Substitute command, the history mechanism replaces an ampersand (&) in new with old . The shell replaces a null old string (s//new/) with the previous old string or string within a command that you searched for with ?string?.
An abbreviated form of the substitute modifier is quick substitution. Use it to reexecute the most recent event while changing some of the event text. The quick substitution character is the caret (^). For example, the command
$ ^old^new^produces the same results as
$ !!:s/old/new/Thus substituting cat for car in the previous event could have been entered as
$ ^car^cat cat /home/jenny/memo.0507 /home/alex/letter.0507 ...You can omit the final caret if it would be followed immediately by a RETURN. As with other command line substitutions, the shell displays the command line as it appears after the substitution.
Modifiers (other than the substitute modifier) perform simple edits on the part of the event that has been selected by the event designator and the optional word designators. You can use multiple modifiers, each preceded by a colon (:).
The following series of commands uses ls to list the name of a file, repeats the command without executing it (p modifier), and repeats the last command, removing the last part of the pathname (h modifier), again without executing it:
$ ls /etc/sysconfig/harddisks /etc/sysconfig/harddisks $ !!:p ls /etc/sysconfig/harddisks $ !!:h:p ls /etc/sysconfig $This table lists event modifiers other than the substitute modifier.
Modifiers
<< prev (1/2)
Modifier Function e (extension) Removes all but the filename extension h (head) Removes the last part of a pathname p (print-not) Displays the command, but does not execute it q (quote) Quotes the substitution to prevent further substitutions on it r (root) Removes the filename extension t (tail) Removes all elements of a pathname except the last x Like q but quotes each word in the substitution individually
-- StephaneDate: Fri, 28 May 2004 13:55:36 +0000 2004-05-28, 14:12(+02), Gabkin:
[...]
> As for zsh, I'm a bash man! (but does zsh have an evolutionary history
> facility like this?)Yes, and much more. Some customizations possible for history:
APPEND_HISTORY <D>
If this is set, zsh sessions will append their history list to the
history file, rather than overwrite it. Thus, multiple parallel
zsh sessions will all have their history lists added to the
history file, in the order they are killed.
EXTENDED_HISTORY <C>
Save each command's beginning timestamp (in seconds since the
epoch) and the duration (in seconds) to the history file. The
format of this prefixed data is:
`:<BEGINNING TIME>:<ELAPSED SECONDS>:<COMMAND>'.
HIST_ALLOW_CLOBBER
Add `|' to output redirections in the history. This allows history
references to clobber files even when CLOBBER is unset.
HIST_BEEP <D>
Beep when an attempt is made to access a history entry which isn't
there.
HIST_EXPIRE_DUPS_FIRST
If the internal history needs to be trimmed to add the current
command line, setting this option will cause the oldest history
event that has a duplicate to be lost before losing a unique event
from the list. You should be sure to set the value of HISTSIZE to
a larger number than SAVEHIST in order to give you some room for
the duplicated events, otherwise this option will behave just like
HIST_IGNORE_ALL_DUPS once the history fills up with unique events.
HIST_FIND_NO_DUPS
When searching for history entries in the line editor, do not
display duplicates of a line previously found, even if the
duplicates are not contiguous.
HIST_IGNORE_ALL_DUPS
If a new command line being added to the history list duplicates an
older one, the older command is removed from the list (even if it
is not the previous event).
HIST_IGNORE_DUPS (-h)
Do not enter command lines into the history list if they are
duplicates of the previous event.
HIST_IGNORE_SPACE (-g)
Remove command lines from the history list when the first
character on the line is a space, or when one of the expanded
aliases contains a leading space. Note that the command lingers
in the internal history until the next command is entered before
it vanishes, allowing you to briefly reuse or edit the line. If
you want to make it vanish right away without entering another
command, type a space and press return.
HIST_NO_FUNCTIONS
Remove function definitions from the history list. Note that the
function lingers in the internal history until the next command is
entered before it vanishes, allowing you to briefly reuse or edit
the definition.
HIST_NO_STORE
Remove the history (fc -l) command from the history list when
invoked. Note that the command lingers in the internal history
until the next command is entered before it vanishes, allowing you
to briefly reuse or edit the line.
HIST_REDUCE_BLANKS
Remove superfluous blanks from each command line being added to
the history list.
HIST_SAVE_NO_DUPS
When writing out the history file, older commands that duplicate
newer ones are omitted.
HIST_VERIFY
Whenever the user enters a line with history expansion, don't
execute the line directly; instead, perform history expansion and
reload the line into the editing buffer.
INC_APPEND_HISTORY
This options works like APPEND_HISTORY except that new history
lines are added to the $HISTFILE incrementally (as soon as they are
entered), rather than waiting until the shell is killed. The file
is periodically trimmed to the number of lines specified by
$SAVEHIST, but can exceed this value between trimmings.
SHARE_HISTORY <K>
This option both imports new commands from the history file, and
also causes your typed commands to be appended to the history file
(the latter is like specifying INC_APPEND_HISTORY). The history
lines are also output with timestamps ala EXTENDED_HISTORY (which
makes it easier to find the spot where we left off reading the
file after it gets re-written).
By default, history movement commands visit the imported lines as
well as the local lines, but you can toggle this on and off with
the set-local-history zle binding. It is also possible to create
a zle widget that will make some commands ignore imported
commands, and some include them.
If you find that you want more control over when commands get
imported, you may wish to turn SHARE_HISTORY off,
INC_APPEND_HISTORY on, and then manually import commands whenever
you need them using `fc -RI'.
I have:
HISTFILE=~/.zsh-history.$ZSH_VERSION
HISTSIZE=500
SAVEHIST=50000
setopt HIST_IGNORE_ALL_DUPS HIST_REDUCE_BLANKS \
HIST_SAVE_NO_DUPS HIST_VERIFY INC_APPEND_HISTORY NO_BANG_HIST
Bash provides two builtin commands that allow you to manipulate the history list and history file.
- fc
fc [-e ename] [-nlr] [first] [last] fc -s [pat=rep] [command]Fix Command. In the first form, a range of commands from first to last is selected from the history list. Both first and last may be specified as a string (to locate the most recent command beginning with that string) or as a number (an index into the history list, where a negative number is used as an offset from the current command number). If last is not specified it is set to first. If first is not specified it is set to the previous command for editing and -16 for listing. If the `-l' flag is given, the commands are listed on standard output. The `-n' flag suppresses the command numbers when listing. The `-r' flag reverses the order of the listing. Otherwise, the editor given by ename is invoked on a file containing those commands. If ename is not given, the value of the following variable expansion is used: ${FCEDIT:-${EDITOR:-vi}}. This says to use the value of the FCEDIT variable if set, or the value of the EDITOR variable if that is set, or vi if neither is set. When editing is complete, the edited commands are echoed and executed. In the second form, command is re-executed after each instance of pat in the selected command is replaced by rep. A useful alias to use with the fc command is r='fc -s', so that typing `r cc' runs the last command beginning with cc and typing `r' re-executes the last command (see section Aliases).- history
history [-c] [n] history [-anrw] [filename] history -ps argDisplay the history list with line numbers. Lines prefixed with with a `*' have been modified. An argument of n says to list only the last n lines. Options, if supplied, have the following meanings:When the `-w', `-r', `-a', or `-n' option is used, if filename is given, then it is used as the history file. If not, then the value of the HISTFILE variable is used.
- -w
- Write out the current history to the history file.
- -r
- Read the current history file and append its contents to the history list.
- -a
- Append the new history lines (history lines entered since the beginning of the current Bash session) to the history file.
- -n
- Append the history lines not already read from the history file to the current history list. These are lines appended to the history file since the beginning of the current Bash session.
- -c
- Clear the history list. This may be combined with the other options to replace the history list completely.
- -s
- The args are added to the end of the history list as a single entry.
- -p
- Perform history substitution on the args and display the result on the standard output, without storing the results in the history list.
vague memory
- If you really are uncertain of the history or if you know you could be searching back through many similar commands for one of particular interest, then you can use this more brute-force method.
- Type the following command to get a list of all related commands with their history numbers:
history | grep -i "<search string>"
- Once you've found the command you want, you can execute it specifically by its number using the following built-in history expansion command:
!<history number>
... ... ...
Here's an example that suppresses duplicate commands, the simple invocation of ls without any arguments, and the shell built-ins bg, fg, and exit:
export HISTIGNORE="&:ls:[bf]g:exit"
O'Reilly ONLamp Blog
If you're like me, you never want to lose a command. I'm constantly searching back through them to find out just what those command line flags were, what the esoteric command is (and where it's located), and most of all: what in Tcl's name did I do last month when I installed foobazzulator. First thing to know: control-r.
However, bash ships with a ridiculously short memory: 500 commands. That's not enough: right now, my powerbook's iTerm prompt is:
[/Users/jwellons]
111280$
Go into your .bash_profile now and add these lines, before you read on:
HISTFILESIZE=1000000000
HISTSIZE=1000000
Unless you're very precocious, that should square you away for about 10 years (I'm at about 22 months since enlightenment).Once you develop control-r as a fast way to search your command history, you'll notice immediate stress relief, and as I do everyday, wish you'd done this years before.
Now that you have commands piling up, you can do more than just use them. You can analyze them too, for fun and profit (since time = money)!
>The basic starter is
cut -f1 -d" " .bash_history | sort | uniq -c | sort -nr | head -n 30In other words, just what do you spend so much time typing? Here's the money: Anything in at least the top ten, assuming it is not from somHistory can be browsed using arrow commands, but more efficient way is to use Ctrl-R for anything but previous half-dozen of commands. Ctrl-R mechanism provides search in history: typed characters can be in any place of the command will autocomplete as soon as there's a match to a history entry, then you just need to hit enter to reexecute the command -time splurge, needs to be aliased to a one or two letter shorthand.
My top command is v for vim, which I've executed 9225 times. If those two extra letters, which require me to switch hands, then use adjacent fingers take an extra half-second each time: that's well over an hour wasted! And what a terribly drudgerous and unhealthy hour it is too: mindlessly typing im 9225 times!
Even worse, who knows how desperately I needed to open that file, and yet I needed to type superfluous characters, probably messing them up on the first three tries.
Actually, that's only my second highest command. cl tops the list at 11116. You see, last time I did this analysis, I noticed I was spending (yes, spent, like lines of code, there is no glory in using a lot of them) many commands first cd'ing to a directory, then listing the contents. Here's cl:
# Compress the cd, ls -l series of commands.
alias lc="cl"
function cl () {
if [ $# = 0 ]; then
cd && ll
else
cd "$*" && ll
fi
}
There you have it, accompanied by its most common typo. Add this to your bash profile now, and you'll add several hours to your life. Hurry! Don't wait! It may not seem like much now, but no one lies on her deathbed wishing she had spent more time first changing directories, waiting for it to return, then typing ls.Since I know you're dying to see the rest, here's my whole thirty, unaliased for readability:
11116 cl
9225 vim
7833 ll The alias of ll depends on the OS I'm on, but for my Mac, it's ls -AGlFT.
5145 cd
4858 clear
4563 rm
3950 alias to log into the master db server at my old workplace
3740 lt version of ll that puts most recently modified stuff at the bottom. Mandatory! Add -tr to ll above
3435 mod a function that does lt, but runs it through tail
3236 mv
2103 ls
1887 grep
1863 perl
1834 df
1767 mzscheme
1679 alias to log into my personal server
1580 g++
1544 cat
1186 scp
1080 find
988 man
925 echo
921 mkdir
907 sudo
888 history
841 alias to log into the dev server at my old workplace
831 cp
763 gpg
758 locate
733 gzip
Depending on response, we may do another section with pie charts, finding all the typo permutations for simple commands (there's a lot), and searching for common sequences.
What I really want to see, though, is your top commands.
2007/09/03 | Builder AU
The amount of commands stored in the history file is dependent on the size of the file you allocate. By default 500 commands are stored, but you can tweak these values by setting the following options in a startup file:
HISTSIZE = 1000 HISTFILE = ~/.bash_historyTo print out the entire history file, you can use the history command:
$ history | tail -10 522 gvim 523 vim .bashrc 524 vim .bash_profile 525 history 526 ls 527 echo $SHELL 528 echo $HISTFILE 529 echo $HISTSIZE 530 vim .bashrc 531 history | tail -10 $The number in the left column is the history item number. This can be bigger than the size of your stored history file, as commands from the current shell are not added to the file until the shell is closed.
You can jump straight to executing any line in your history by typing an '!' followed by the item number. So for example if we wanted to echo the shell name to the console again we could write echo $SHELL or simply:
$ !527 /bin/bash $Searching command history
You can also use the ! command to search through the history, by replacing the item number with characters from the start of the command. The previous example can now just as easily be written:
$ !echo echo $SHELL /bin/bash $Often this becomes unwieldy since you have to match the command from the beginning, and many commands start in the same way (eg. "echo $HISTFILE", "echo $HISTSIZE", "echo $SHELL"). You can always hack something together using history and grep, but there's an easier way with the '!?' command. '!?' followed by a simple string, executes the last command in the history that contains that string.
So, to reprint the name of the shell we could have simply typed:
$ !? SHELL /bin/bash #More usefully, you can interactively search the command history at the console by hitting CTRL-R at the prompt and typing the section of the string you are looking for. You can only use CTRL-R interactively, that is, not in a script (although relying on the history in a script can be dangerous anyway), but it can save you more keystrokes as it displays the match at each point, meaning you can stop searching once you've found it.
April, 2006 (samag.com) When used as an audit utility, shell history has serious drawbacks. For example:
- Once a shell history file contains the maximum number of commands, old commands are removed as new ones are entered.
- History files may be modified by a user who is trying to cover his tracks.
Timestamps are not available to determine when a command was executed.
- History files are typically stored in the user's home directories making it difficult to process the information.
- It can be tricky to tell who executed certain commands if someone used su to become another user, such as root.
09.27.2006 | Techtarget.com
The Bash shell is the default shell environment in most Linux distributions, including all flavours of Red Hat. One default feature of the Bash shell is to record a history of all the commands entered by a user in a log file called .bash_history, found in the user's home directory.
The history in this file can be retrieved from the command line using the more or cat binaries or by using the internal Bash command, history. For many users, it is useful to retrieve the previously executed commands, usually to save the effort of re-typing them.
So why might we want to limit or disable this Bash command history? Well, among the commands that your users type are file names, command names, IP addresses, passwords and a myriad of other data that are potentially valuable to an attacker intent on subverting or compromising your host. Keeping a record of this data means an attacker may only need to compromise an individual .bash_history file rather than a more difficult source of data.
To limit the size and behaviour of the .bash_history file, you need to edit the behavior of the shell in the /etc/profile file (the central version of the .bash_profile file usually contained in users home directories). Add or change the following three lines to the file:
export HISTSIZE=100 export HISTFILESIZE=100 unset HISTFILEThe first two lines set the length and size of the history stored in the file. The last line unsets the HISTFILE variable that tells the Bash shell not to save history when the user logs out of the interactive session. This means an online user will only be able to see the history of the last 100 commands, and that history will disappear after the user logs out of the host.
A further way to ensure the command history is removed is to include a command in the .bash_logout file (other shells use the .logout file). The contents of the .bash_logout file are executed when the user logs out. You can see a simple .bash_logout file on the following lines:
# ~/.bash_logout /bin/rm -f $HOME/.bash_history clearThe rm command will remove the .bash_history file from the users home directory when the user logs out. To add this to the file you can edit the .bash_logout file contained in the /etc/skel directory (the contents of this directory are copied to the home directories of all new users when they are created). Existing users will need the .bash_logout files in their home directories adjusted to add the command.
There is, however, one gotcha associated with this change, and that is that if an attacker has compromised your host, then the history of their actions might not be recorded. Of course, any talented attacker will use other means (including this exact method and others like the deletion or editing of log files) to remove that history.
Linux.com
Entering the history command without any switches displays the history list with line numbers. If that's too much information, enter history N where N is the number of previously executed commands you want displayed.
Bash also allows for incremental search on the history list. Use ctrl+r for a backward/reverse search or ctrl+s to perform a forward search. As you type the first few letters of the command, the last command from the history list that matches with your string would be displayed.
Since you are at the command line, you can club combine some popular commands and cook up interesting surprises. One such example is to pass history through grep along with the first few letters of a command. For example, try this simple hack, which displays all the commands beginning with the letters you supply:
history | grep -i first-few-letters-of-command
History expansion
History expansion serves two purposes, the first is repeating a command from the history list. The second is selecting portions from a command for substituting into the current command.
History expansions are implemented by the history expansion character '!'. The line selected from the history list is called 'event' and portions of that command that are selected are called 'words'. Depending on your needs, you can either use 'word' or 'event designators'.
Event designators
Event designators, invoked by the history expansion character are used for command substitution, that is, repeating a command from the list. ! starts history substitution. It can be escaped with a backslash (\), since it is a special character. In this example, history command 1008 -- a simple ls -- is repeated:
!1008
ls
animate
Desktop
DOWNLOADS
evolution
songs
sonu_result.png
star trekAnother useful event designator is !string, which runs the most recent command beginning with the string you specify.
Word designators
Word designators are used to select specified words from an event. A colon (:) is used to separate word designators from events. Words in a command are numbered from the beginning of the line, with the first word denoted by zero (0). Once selected, a word is inserted into the current command separated by a single space.
Some common word designators are n, which refers to the nth word; ^ refers to the first word; $ refers to the last word and * refers to the complete line entry except for the first word, which is the command.
For example, !conv:5 displays the fifth word from the last command beginning with !conv, while !conv:$ would display the last word from the same command. Please note that !conv:* is same as !conv:1-$ - both resulting in the complete command except for the first word.
Modifying selected words
There are a number of modifiers that help you to describe how you want the selections to behave. Each modifier in a command needs to be preceeded with a colon (:) and you can use more than one modifier in a command. A very popular modifier is p which results in the command being listed instead of being executed. For example:
!l:p
ls -lThere is also a search-and-replace type modifier that you can use when you wish to replace some text with some other. This modifier is s/old/new. For example:
!!:s/-l/-a/ ls -a [...] Note: A !! is used to refer to the last command in the history list. The last command was ls -l and so the -l was replaced with -a and the new command, ls -a was executed.Conclusion
After encountering a thread in a popular forum board that just brushed on Bash and its event designators, I've since done enough reading from the man pages and the web to officially declare that it is a very cool feature which requires very little effort to get hooked on.
The usage of the bash-history feature could be as fun as helpful, also it can save a lot of time if you are one of those who use bash-terminals for everything (if you are not, what the hell are you doing here with Linux Mr. Green ...just kidding Wink )
I'm not going to talk in extent about the usage of bash-history, I only want to show you a couple of tips. If you want to learn more about it you can take a look to the chapter 7 of the Bash Reference Manual (such as ramfree "pointed" long time ago, should be under every linux user's pillow Wink )
Here are the tips:
$HISTIGNORE or How-To improve the history usage:
$ !nWill execute the line n of the history record.- !-n
Will execute the command n lines back.
!! --Will execute the last command. As !-1 or "up-arrow + return" !stringWill execute the most recent command starting with the given string. # In my experience string is just the first characters of the first word of the command, so don't use space characters. !?string[?]Will execute the most recent command containing the given string.# # The last "?" may be omitted if the string is followed by a new line. So if the string includes space characters or similar close it with "?". This can be used to avoid the error that appears with !string when used with long strings. $ ^string1^string2 --String2 will substitute string1 on the last command.
Cool, isn't it? This is equivalent to !!:s/string1/string2/ which is cooler. Any one feels a bit like in vi?
You might want to set up the shell variable $HISTIGNORE to avoid having consecutive duplicate commands or unuseful commands appended to the history list. So you'll get rid of the never ending story of hitting the up arrow trough simple and repetitive commands.Here is an example of usage:
export HISTIGNORE="&:l[sl]:[fb]g:exit"
Setting this way the $HISTIGNORE, the consecutive duplicated commands, the simple calls to ls, ll, fg and bg commands without arguments, and calls to the exit command will not be appended to the history list, so navigate though it will be much easier.
Mark Stosberg# BASH HISTORY SEARCH AND REPLACE ^string1^string2^ Quick substitution. Repeat the last command, replacing string1 with string2. Equivalent to ``!!:s/string1/string2/'' # MORE BASH COMMAND LINE TRICKERY (messing with the history) make a directory then move into it: mkdir cgi-bin; cd !#$ !#$ is shorthand for "the first word of this command". If I wanted to pick the third word out of the previous command, that would be: !!:3 (don't forget there is a zeroth word). # execute the most recent command the contains the following string: !?string # globally search replace on the previous line: !!:gs/old/new/ # HEADS AND TAILS ever wanted to copy a few files in the same directory, all of which have same long prefix, like: cp /usr/local/etc/apache/file1.txt /usr/local/etc/apache/file2.txt you can grap and reuse that prefix. It's named !#:1:h like: cp /usr/local/etc/apache/file1.txt !#:1:h/file2.txt !#:1:h/file3.txt # SAVING A COMMAND WITHOUT EXECUTING While using bash, if you have typed a long command, and then realize you don't want to execute it yet, don't delete it. Simply append a # to the beginning of the line, and then hit enter. Bash will not execute the command, but will store it in history so later you can go back, remove the # from the front, and execute it. # GOING FORWARD A BACK A WORD META-F goes forward a word META-B goes backward a word # COMPARE A FILE WITH IT'S VARIOUS VERSIONS IN THE SAME DIRECTORY diff file.* # EXAMPLE of a basic command line script % for f in `ls | grep -v ".sh"`; { mv ${f} ${f}.sh } # searching the history Cntrl-R starts a reverse incremental search # Keyboard shortcuts: CTRL-k: delete ('kill') from cursor position to the end of the line * CTRL-u: delete from cursor position to the beginning of the line * ALT-d: delete from cursor position to the end of the current 'word' * CTRL-w: delete from cursor position to the beginning of the current 'word' * CTRL-a: move cursor to the first character of the line * CTRL-e: move cursor beyond the last character of the line * ALT-a: move cursor to the first character of the current 'word' * ALT-e: move cursor to the last character of the current 'word' * CTRL-y: insert latest deleted 'word' * ESC-_ or !$: repeats the last argument of the previous command. Example: You created a directory with mkdir /usr/local/bin/peter/pan. Now you want to change into that directory with cd. Instead of typing the path again, you type cd ESC-_ or # Diff 2 files with a common base: diff {alpha,beta}site/config/Config.pl
#!/bin/bash # # gh - grep history # # A simple script for the forgetful and lazy (I use it all the time). # # This script allows you to re-use bash history commands... # # A: ...if you can't remember the whole command or path... # B: ...if you don't feel like pressing the "up" arrow for 2 minutes... # C: ...if you are too forgetful or lazy to type "grep <search-string> ~/.bash_history"! # # -Mike Putnam http://www.theputnams.net # # Usage: gh <search-string> # grep $1 ~/.bash_history exit 0
On Sat, 5 May 2001, Joost van der Lugt wrote:
Hi all,
I've been looking into this for a litle bit and am unable to find an answer. This is a feature AFAIK only implemented by SuSE:
At a prompt type one or more characters then use Page Up/Page Down to scroll through all commands that started with these characters.
So typing:cd
would then give a 'scrollable' list of anything that started with cd simply hit enter when you reach the command you were looking for.
I know Ctrl-r and am familiar with ! but they are not as nice, and really not the same. Would anybody have a clue as to how this could be implemented?
I don't think it is shell dependent, so I don't think it's a bash option but I could very well be wrong.
(Tried the dotfile generator, but don't see anything there)The option is _really_ addictive therefore my post:)
Thanks,--
Cheers,Joost van der Lugt
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]>
Google matched content |
[Jul 02, 2020] 7 Bash history shortcuts you will actually use by Ian Miell Published on Oct 02, 2019 | opensource.com
PDF format (.pdf):
Download link: bash history cheat sheet
(.pdf)
Downloaded: 22011 times
ASCII .txt format:
Download link: bash history cheat sheet
(.txt)
Downloaded: 5800 times
A history substitution begins with a !, and may occur anywhere on the command line. The power of history substitution is impressive. There are too many ways of using it to explain here, but complete details can be found in the csh man page. Some of the simpler forms are:
!! Refer to the previous command !n Refer to command-line n !-n Refer to the current command-line minus n. !str Refer to the most recent command starting with str. !?str Refer to the most recent command containing str.You can also refer to individual words of a previous command. If necessary, you can separate the event specification (above) from the word specification.
!!:0 The first word of the previous command line !!:n The nth argument of the previous command !!:$ The last argument of the previous command !!:* All of the arguments of the previous commandFurther modification to the commands can be done including editing particular words, but we won't go into further detail here. Suffice it to say that there's probably a way to do whatever it is you are trying to accomplish with history substitution.
Quick substitution can be done, if all you want to do is change a single string from the previous command. For instance, if you just sent mail to dela with "mail dela", and now want to send mail to kaser, you can say
^dela^kaser^
and the string "dela" will be replaced with "kaser".
bash stores the commands you type and provides access to them through its history mechanism. This makes it possible to repeat a previous command, include portions of a previous command in the current command or re-execute a previous command after fixing a typing error.
The list of all commands currently saved by the history mechanism is displayed by executing the history command. The history commands numbers the old commands it displays. Typing
!nwill re-execute the command numbered n.If you would rather not lookup the number of a previous command, you can type ! followed by the first characters of the command. For example,
!lswill execute the last command that began with ls.Another way to avoid looking up the number is to use control-p. Pressing control-p will display your previous command, which you can then edit. Repeatedly pressing control-p will go back to earlier commands.
If the command you want to execute is similar to a previous command, or you want to fix a typing mistake, you can control-p back to the command, then edit it using control-b or the left arrow key to move the cursor back a character, contol-f or the right arrow key to move forward a character, control-a to move to the beginning of a line, control-e to move to the end of a line, and control-d to delete a character. Backspace and Delete work as usual. Anything you type is inserted where the cursor is located.
Another useful function the history mechanism provides is the ability to re-use the arguments of the previous command. The characters !* occurring in a command are replaced by the arguments to the previous command. Thus, one can first check the contents of a file by typing
and then print the file by typingless somelongfilenamelp !*You can avoid typing somelongfilename by just typing enough of it so that the shell can recognize it, (for example ``somel'' for the filename ``somelongfilename'') and pressing tab. bash will type the rest of the filename for you. If there is another file of a similar name, such as ``somelongfile2'', and you use tab to complete the name, bash will type the beginning of the two filenames until it encounters a discrepancy. In this case, it would type ``somelongfile''. Then it will beep and wait for you to finish typing in the filename of your choice.
Finally, you can fix simple typing mistakes in a command by typing
^old-string^new-stringThis causes the shell to re-execute the last command after first replacing the first occurrence of old-string by new-string.
Word designators are used to select desired words from the event. A `:' separates the event specification from the word designator. It may be omitted if the word designator begins with a `^', `$', `*', `-', or `%'. Words are numbered from the beginning of the line, with the first word being denoted by 0 (zero). Words are inserted into the current line separated by single spaces.
For example,
- !!
- designates the preceding command. When you type this, the preceding command is repeated in toto.
- !!:$
- designates the last argument of the preceding command. This may be shortened to !$.
- !fi:2
- designates the second argument of the most recent command starting with the letters fi.
Here are the word designators:
- 0 (zero)
- The 0th word. For many applications, this is the command word.
- n
- The nth word.
- ^
- The first argument; that is, word 1.
- $
- The last argument.
- %
- The word matched by the most recent `?string?' search.
- x-y
- A range of words; `-y' abbreviates `0-y'.
- *
- All of the words, except the 0th. This is a synonym for `1-$'. It is not an error to use `*' if there is just one word in the event; the empty string is returned in that case.
- x*
- Abbreviates `x-$'
- x-
- Abbreviates `x-$' like `x*', but omits the last word.
If a word designator is supplied without an event specification, the previous command is used as the event.
History expansion is similar to csh 's. It is enabled by default in interactive shells. History expansion
happens before the shell breaks the input into words, although quoting is recognized and quoted text is
treated as one history ''word''. History substitution is performed on history events , which consist of an event designator (which previous line to start with), a word designator (which word from that line to use, starting with zero), and one or more optional modifiers (which parts of the words to use).
Colons separate the three parts, although the colon between the event designator and word designator may be omitted when the word designator begins with ˆ , $ , * , − , or % . Each modifier is separated from the nextone with a colon. The histchars variable specifies the start-of-history and quick substitution characters, and also the comment character that indicates that the rest of a line is a comment. The previous command is the default event if no event designator is supplied.
The event designators are:
start a history substitution
- ! --
! n -- command line n !−n -- current line minus n ( n previous) !! -- the previous command !str -- most recent command line starting withstr !? str [ ? ] -- most recent command line containing str !# -- the entire command line typed so far ˆ old ˆ new ˆ quick substitution: repeat last command changing old to new The word designators are: 0 the zero'th word (command name) n word n ˆ the first argument, i.e., word one $ the last argument % the word matched by the most recent !? str ? search x − y words x through y . −y is short for 0−y * words 1 through the last (like 1−$ ) n * words n through the last (like n −$ ) n −words n through the next to last The modifiers are:
remove all but the suffix of a filename
- e
g make changes globally, use with s modifier, below h remove the last part of a filename, leaving the ''head'' p print the command but do not execute it q quote the generated text r remove the last suffix of a filename s/ old / new / substitute new for old in the text. Any delimiter may be used. An & in the replacement means the value of old. With empty old , use last old , or the most recent !? str ? search if there was no previous old t remove all but the last part of a filename,leaving the ''tail'' x quote the generated text, but break into words at blanks and newline & repeat the last substitution
Bash provides two builtin commands that allow you to manipulate the history list and history file.
fc [-e ename] [-nlr] [first] [last] fc -s [pat=rep] [command]Fix Command. In the first form, a range of commands from first to last is selected from the history list. Both first and last may be specified as a string (to locate the most recent command beginning with that string) or as a number (an index into the history list, where a negative number is used as an offset from the current command number). If last is not specified it is set to first. If first is not specified it is set to the previous command for editing and -16 for listing. If the `-l' flag is given, the commands are listed on standard output. The `-n' flag suppresses the command numbers when listing. The `-r' flag reverses the order of the listing. Otherwise, the editor given by ename is invoked on a file containing those commands. If ename is not given, the value of the following variable expansion is used: ${FCEDIT:-${EDITOR:-vi}}. This says to use the value of the FCEDIT variable if set, or the value of the EDITOR variable if that is set, or vi if neither is set. When editing is complete, the edited commands are echoed and executed. In the second form, command is re-executed after each instance of pat in the selected command is replaced by rep. A useful alias to use with the fc command is r='fc -s', so that typing `r cc' runs the last command beginning with cc and typing `r' re-executes the last command (see section Aliases).
history [-c] [n] history [-anrw] [filename] history -ps argDisplay the history list with line numbers. Lines prefixed with with a `*' have been modified. An argument of n says to list only the last n lines. Options, if supplied, have the following meanings:
Word designators are used to select desired words from the event. A `:' separates the event specification from the word designator. It may be omitted if the word designator begins with a `^', `$', `*', `-', or `%'. Words are numbered from the beginning of the line, with the first word being denoted by 0 (zero). Words are inserted into the current line separated by single spaces.
For example,
- !!
- designates the preceding command. When you type this, the preceding command is repeated in toto.
- !!:$
- designates the last argument of the preceding command. This may be shortened to !$.
- !fi:2
- designates the second argument of the most recent command starting with the letters fi.
Here are the word designators:
- 0 (zero)
- The 0th word. For many applications, this is the command word.
- n
- The nth word.
- ^
- The first argument; that is, word 1.
- $
- The last argument.
- %
- The word matched by the most recent `?string?' search.
- x-y
- A range of words; `-y' abbreviates `0-y'.
- *
- All of the words, except the 0th. This is a synonym for `1-$'. It is not an error to use `*' if there is just one word in the event; the empty string is returned in that case.
- x*
- Abbreviates `x-$'
- x-
- Abbreviates `x-$' like `x*', but omits the last word.
If a word designator is supplied without an event specification, the previous command is used as the event.
- accept-line (Newline or Return)
- Accept the line regardless of where the cursor is. If this line is non-empty, add it to the history list according to the setting of the HISTCONTROL and HISTIGNORE variables. If this line is a modified history line, then restore the history line to its original state.
- previous-history (C-p)
- Move `back' through the history list, fetching the previous command.
- next-history (C-n)
- Move `forward' through the history list, fetching the next command.
- beginning-of-history (M-<)
- Move to the first line in the history.
- end-of-history (M->)
- Move to the end of the input history, i.e., the line currently being entered.
- reverse-search-history (C-r)
- Search backward starting at the current line and moving `up' through the history as necessary. This is an incremental search.
- forward-search-history (C-s)
- Search forward starting at the current line and moving `down' through the the history as necessary. This is an incremental search.
- non-incremental-reverse-search-history (M-p)
- Search backward starting at the current line and moving `up' through the history as necessary using a non-incremental search for a string supplied by the user.
- non-incremental-forward-search-history (M-n)
- Search forward starting at the current line and moving `down' through the the history as necessary using a non-incremental search for a string supplied by the user.
- history-search-forward ()
- Search forward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search. By default, this command is unbound.
- history-search-backward ()
- Search backward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search. By default, this command is unbound.
- yank-nth-arg (M-C-y)
- Insert the first argument to the previous command (usually the second word on the previous line) at point. With an argument n, insert the nth word from the previous command (the words in the previous command begin with word 0). A negative argument inserts the nth word from the end of the previous command.
- yank-last-arg (M-. or M-_)
- Insert last argument to the previous command (the last word of the previous history entry). With an argument, behave exactly like yank-nth-arg. Successive calls to yank-last-arg move back through the history list, inserting the last argument of each line in turn.
HISTCONTROL
HISTCONTROL A value of 'ignorespace' means to not enter lines which begin with a space or tab into the history list. A value of 'ignoredups' means to not enter lines which match the last entered line. A value of 'ignoreboth' combines the two options. Unset, or set to any other value than those above, means to save all lines on the history list. The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of HISTCONTROL. If the list of values includes ignorespace, lines which begin with a space character are not saved in the history list. A value
of ignoredups causes lines matching the previous history entry to not be saved. A value of ignoreboth is shorthand for ignorespace and
ignoredups. A value of erasedups causes all previous lines matching the current line to be removed from the history list before that
line is saved. Any value not in the above list is ignored. If HISTCONTROL is unset, or does not include a valid value, all lines read
by the shell parser are saved on the history list, subject to the value of HISTIGNORE. The second and subsequent lines of a multi-line
compound
command are not tested, and are added to the history regardless of the value of HISTCONTROL.
In bash 3.0 HISTCONTROL can be set to `erasedups' option, which causes all lines matching a line being added to be removed from the history list.
export HISTCONTROL=erasedups
You might want also to set up the shell variable HISTIGNORE to avoid useless command littering you history. Natural candidates are cd -, all variants of ls without argument, ll, etc.
export HISTIGNORE="&:l[sl]:[fb]g:cd \-"
Setting this way the $HISTIGNORE, the consecutive duplicated commands, the simple calls to ls, ll, fg and bg commands without arguments, and calls to the exit command will not be appended to the history list, so navigate though it will be much easier.
An event designator references a command line stored in the history file. There are several formats of event designators, they are as follows.
! | Start a history substitution command, except when followed by a space, tab, new-line, =, or (. |
!! | Reference the previous command line. Typing !! and pressing Return executes the previous command. |
!n | Reference command line with event number n from the history file. This references a specific event number. For example, if the current event number is 7, you can specify an event number from 1 to 6. The command !3 would reexecute event 3, vi wsr.092989. |
!-n | Reference the nth previous command event. The current event number -n. For example, if the current event number is 7 and you type !-3, event number 4 is executed. |
!str | Reference the most recent command line starting with string str. For example, !vi reexecutes the "vi apiprog.c" command. |
!?str[?] | Reference the most recent command line containing the string str. For example, !?dly reexecutes the "find ..." command. |
!{str} | Insulate a reference string from adjacent characters. |
Word designators provide a way to reference specific arguments (words) from a command line stored in the history file. A colon (:) separates the event designator and the word designator. If the word designator begins with $, %, ^, *, or - the : is not needed. If you want the word to be selected from the previous command line, the second ! is not required. For example, !!:2 and !:2 both refer to the second word on the previous command. Words are zero relative, that is, word zero is the command itself. The first argument (arg1) on the command line is word 1.
The available word designators are as follows:
You can add modifiers after the word designators. A modifier is used to modify the referenced command line. Each modifier must be preceded with a colon (:).
It make sence to try command with modifier :p in case the connad is destructive (like rm and rmdir commands are) Suffix :p allows to print a command, but not execute it. Another three useful modifers are:
Let's say I'm reading a file nested deeply in a directory structure. When I finish editing the file, I realize that there are some other operations I want to do in that directory and that they would be more easily accomplished if I were in that directory. I can use :h to help get me there.
links /usr/local/share/doc/3dm/3DM_help.htm cd !$:h links !-2 $:t
As we see !$ can be modified by :h.
In our next example, we've downloaded a tarball from the Internet create directory with the name of the tarball and unpack the tarball into it. We check
wget http://www.example.com/path/to/test.tgz mkdir !$:r cd !$ tar xzvf ../test.tgz
The second command will create a directory called 'test' in the current directory.
Word modifiers can be stacked as well. Here is more complex example, in which we'll first download a file to /tmp, and then create a directory for the contents of that tar file in /usr/local/src and then unpack the tarball into it:
cd /tmp wget http://www.example.com/path/KickassApplicationSuite.tar.gz cd /usr/local/src/ mkdir !-2$:t:r:r {creates directory called 'KickassApplicationSuite'} cd !$ tar xvzf /tmp/!-4$:t
The first three commands are fairly common and use no substitution. The fourth command, however, seems like gibberish. We know !-2 means the command prior to the most recent one and that $ indicates the last argument of that command. We even know that :t will strip off the path portion of that argument (in this case, even the "http://".) We even know that :r will remove the file-extension to that argument, but here we call it twice, because there are two extensions (.gz is removed by the first :r and .tar is removed by the second.) We then cd into that directory (!$ again, is the argument to the previous command, in this case the argument to mkdir, which is 'KickassApplicationSuite'.) We then untar the file. !-4$ is the last argument to the command four commands ago, which is then modified by :t to remove the path, because we added the path as /tmp/. So the last command becomes tar xvzf /tmp/KickassApplicationSuite.tar.gz.
There's even a word modifier for substitution. :s can be used similarly to circumflex hats to do simple line substitution.
vi /etc/X11/XF86config !!:s/config/Config-4/
We know that !! means the previous command string. :s modifies the previous command, substituting the first argument to :s with the second argument to :s. My example used / to delimit the two arguments, but any non-whitespace character can be used. It's also important to note that, just like circumflex hat substitution, the substitution will only take place on the first instance of the string to be substituted. If you want to affect every instance of the substitution string, you must use the :g word modifier along with :s.
mroe file1 ; mroe file2 !!:gs/mroe/more
The second command substitutes (:s) more for all (:g) instances of mroe. Hint: :g can be used with circumflex hats too!
The final word modifier we'll look at in this tutorial is &. & means repeat the previous substitution. Let's say we're examining file attributes with the ls command.
ls -lh myfile otherfile anotherfile !!:s/myfile/myfile.old/
Seems simple enough. :s steps in and changes myfile to myfile.old so we end up with ls -lh myfile.old myfile2 myfile3. & is just a shortcut that we can use to represent the first argument to :s The following example is equivalent to the example above:
ls -lh myfile otherfile anotherfile !!:s/myfile/&.old/
The following examples illustrate how to use the Event Designators, Word Designators, and the Modifiers.
When used as an audit utility, shell history has serious drawbacks. For example:
- Once a shell history file contains the maximum number of commands, old commands are removed as new ones are entered.
- History files may be modified by a user who is trying to cover his tracks.
Timestamps are not available to determine when a command was executed.
- History files are typically stored in the user's home directories making it difficult to process the information.
- It can be tricky to tell who executed certain commands if someone used su to become another user, such as root.
Society
Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers : Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism : The Iron Law of Oligarchy : Libertarian Philosophy
Quotes
War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda : SE quotes : Language Design and Programming Quotes : Random IT-related quotes : Somerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose Bierce : Bernard Shaw : Mark Twain Quotes
Bulletin:
Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 : Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law
History:
Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds : Larry Wall : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOS : Programming Languages History : PL/1 : Simula 67 : C : History of GCC development : Scripting Languages : Perl history : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history
Classic books:
The Peter Principle : Parkinson Law : 1984 : The Mythical Man-Month : How to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite
Most popular humor pages:
Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor
The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D
Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.
This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...
|
You can use PayPal to to buy a cup of coffee for authors of this site |
Disclaimer:
The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.
Last modified: May 29, 2021