Is it possible to echo and redirect history commands into a script file by the ! command? Is there variation of the pipe, redirect, or tee commands I am overlooking?

  518  xmodmap -e "keycode 66 = Return"
  519  xmodmap -e "keycode 23 = Tab"
  535  xmodmap -e 'clear Lock' -e 'keycode 0x42 = Escape'

[Tech_Ministry@localhost ~]$ echo !535 && !518 >> xmodmap_-e.sh 
echo xmodmap -e 'clear Lock' -e 'keycode 0x42 = Escape' && xmodmap -e "keycode 66 = Return" >> xmodmap_-e.sh 
xmodmap -e clear Lock -e keycode 0x42 = Escape

After reading this post I tried echo !535:p && !518:p >> xmodmap_-e.sh

I feel as if I am missing something simple.. Is it possible to do this? Possible to echo each command to a separate line?

2 Answers 2


From help history:

  -p    perform history expansion on each ARG and display the result
    without storing it in the history list

What I usually do is, for example, history -p \!572 >> myfile to save command 572 from the history.

For your example, I would use:

echo "$(history -p '!535') && $(history -p '!518')" >> xmodmap_-e.sh

though there is probably a way to do this with a single history command.

(That puts both commands on a single line in the script file, joined with the && operator.)

UPDATE: The simpler form I was looking for when I wrote this was:

history -p \!535 \!518 >> whatever.sh

If you enclose the history marker in double quotes you can capture its expansion as a quoted string:

echo "!535 && !518" >> xmodmap_-e.sh 

The reason your published attempt failed is because the && wasn't quoted, so was actioned:

echo !535 && !518 >> xmodmap_-e.sh

This expanded into the two commands:

echo {the expansion of !535}
{run the expansion of !518} >> xmodmap_-e.sh

So the first expansion would have been written to stdout, and since the echo would have succeeded, the second one would have been executed with any of its ensuing output being appended to the file xmodmap_-e.sh.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .