Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

The command printf "#!/bin/bash\n" > t generates an error(bash: !/bin/bash\n": event not found), but hitting the up key does not recall the command so that I can modify it. Why is that?

(What I was trying for here can be accomplished with printf "%s\n" '#!/bin/bash' >t I am trying to learn Bash and really want to understand why bash history doesn't capture the previous printf command.)

share|improve this question
1  
you need to set +H to make it work –  val0x00ff Oct 29 '13 at 14:08
    
The solution I have works. I really just wanted to know why the first thing I tried didn't end up in the bash history. –  William Everett Oct 29 '13 at 14:36
2  
Reason: see @wingedsubmariner answer. Now as a solution: change it to printf '#!/bin/bash\n' > t . That time as it's within Single Quotes, the "!" won't be interpreted as the special "!" history character and the command will work. –  Olivier Dulac Oct 29 '13 at 18:27
    
Also keep in mind that if HISTIGNORE is set, matching commands (typically starting with a space) will be ignored. This is handy to set and use when you need to use command-line passwords. –  kmarsh Oct 29 '13 at 19:24
1  
In my shell printf '\n' does indeed print a newline, so @OlivierDulac's suggestion should work. The interpretation of \n as a newline is being done by printf, not when reading the argument, so the kind of quotes doesn't matter. –  wingedsubmariner Oct 29 '13 at 22:07
show 1 more comment

2 Answers

up vote 10 down vote accepted

The ! character triggers history expansion, as you discovered. This step occurs before a command is saved to the history, so that it can saved into the history with the expansion already done. When an error occurs in history expansion, bash stops processing the command, and so it never gets saved into the history.

History expansion allows previous commands or parts of previous commands to be substituted into the current command. If this was done before saving the command to the history, it could mean something different each time it is executed, because the previous commands are different in each instance. See http://www.gnu.org/software/bash/manual/bashref.html#History-Interaction

For reference, zsh's behavior is different. It will save the command but with the history expansion missing.

share|improve this answer
    
Not sure why you got downvoted, but this answered my question very nicely. Thank you. –  William Everett Oct 29 '13 at 14:20
add comment
 bash: !": event not found

This is because, in the default settings for an interactive shell, Bash performs csh-style history expansion using the exclamation point. This is not a problem in shell scripts; only in interactive shells.

The easiest solution is unsetting the histexpand option: this can be done with set +H or set +o histexpand.

You can read more about this here on the Bash Pitfalls website.

share|improve this answer
1  
This doesn't answer OP's question, it only explains an error he already solved. –  wingedsubmariner Oct 29 '13 at 14:17
1  
@wingedsubmariner I was pointing to the wiki. I also mentioned the histexpand. The whole problem in this case is the exclamation mark (!). –  val0x00ff Oct 29 '13 at 14:20
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.