I'm trying to write a simple script to take a previous command that was (accidentally) written in a non-English layout, convert everything into correct symbols and run it. I'm using Bash 4.3.11.

My current code looks like this (I'm not a programmer, just trying to learn this for general usability):

echo !! | sed -e "y/first-set-of-symbols/second-set-of-symbols/" | bash

The problem is, when I run the script from a file, I get this: "bash: line 1: !!: command not found", but when I just copy paste the whole command, it does what it's expected to do; if I change the echo part to something like "echo test-command" in the script file, that works when I run the script, too.

Could someone please help me understand why !! isn't working from a script here? Is it supposed to?

I am also open to any suggestions on how to do what I'm trying to do in a better / more efficient / more elegant way.

(I'm not using tr, because, apparently, it doesn't work with Unicode, or so they say—at least it doesn't work for me at all.)

  • 1
    I don't have eact ref, however, in a script mode, !! ( previous command) might not be defined, thus sed turn !! into !! and | bash (pipe bash) search for a command named !!
    – Archemar
    Oct 23, 2015 at 8:22
  • 1
    ^ most likely that. Another possible cause: !! is not expanded inline. I'd say tho that you need to pass the broken command as an argument, not try to fetch it from the terminal history. Could you add some more code to get a better insight? That said, trying to auto-correct commands seems like a very bad idea, especially if you run something as root.
    – berbt
    Oct 23, 2015 at 8:37
  • @bert, yeah, I'm only going to use this with something like running a program. I occasionally forget to switch keybord layouts and type garbage which, I thought, would be rather easy to automatically convert into what would have been typed had the keyboard layout been English. Thanks for advice, I certainly am not going to run this with potentially destructive commands, let alone while doing anything as root.
    – Unco Lober
    Oct 23, 2015 at 17:09

2 Answers 2


The !! shortcut is only valid for an interactive session. In all other situations it's treated as a literal pair of characters.

Copy'n'paste this to see what's going on:

cat >/tmp/pling.sh <<x
echo hello, world
echo you said !!

# Now make the file executable
chmod a+x /tmp/pling.sh

# Now run it

Command history isn't enabled in scripts. Even if you enable it, the script has no access to the history of the interactive shell that called it.

Instead of writing a script, make ti a function and put it in your .bashrc.

Also, instead of executing the command in a separate instance of bash, you should probably use the eval builtin to execute it in the same context (same shell variables in particular).

Your approach with history expansion only works for simple commands; commands containing special characters will result in syntax errors or other unintended behavior. Use the fc builtin to access the history programmatically.

reexecute () {
  eval "$(fc -l -1 | sed …)"
  • Thanks a bunch, looks like this solves my problem. (Although, yeah, I'm starting to doubt that I should do what I'm trying to do at all.)
    – Unco Lober
    Oct 23, 2015 at 17:20

You must log in to answer this question.

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