0

I'm using zsh with oh-my-zsh. I'm trying something very simple:

alias fu='sudo !!'

So, if I issued a command that needed a forgotten sudo I could quickly re-do it.

Yes, I googled for that and I even saw several examples but NONE worked for me. For example:

ls
bla bla
!!
zsh: command not found: !!

I also tried:

ls
bla bla
fc -e : -1
bla bla
# that worked! But let's see with sudo...
ls
bla bla
sudo fc -e : -1
# nothing happens!

Another:

alias redo='sudo $(history -p !!)'
# didn't work

I've tried in Mac and Ubuntu, same issues.

alanwilter
  • 498
  • 1
  • 3
  • 20
  • History expansion is done before alias expansion. Hence, your `!!` doesn't get expanded. – user1934428 Jun 03 '20 at 11:15
  • I've read [here](http://zsh.sourceforge.net/Doc/Release/Expansion.html) and I can't find out why `!!` does not work on my `zsh` terminal. So the whole thing is why my first example is not working. – alanwilter Jun 03 '20 at 12:37
  • You have the `!!` inside an alias definition, and as you can see from the link you provided yourself, alias expansion comes later than history expansion. – user1934428 Jun 03 '20 at 12:40

1 Answers1

3

Just an idea (not tested), based on the link you provided in your question (but which explains a bash solution): Instead of an alias redo, you create a function of this name. Inside the function, you can do a

local last_hist=( $(fc -l -1) )

which stores the most recently executed command into the array last_hist, but prefixed by the history number. You remove the history number by

shift last_hist

and execute your sudo command by

sudo "${last_hist[@]}"

However, is it so much more work to just write

sudo !!

instead of your carefully crafted function

redo

?

user1934428
  • 19,864
  • 7
  • 42
  • 87
  • Your suggestion is a good start, I did this in order to get it working: `function fu { local last_hist=( $(fc -l -1) ); shift last_hist; doit="sudo $last_hist"; echo "$doit"; eval $doit }` – alanwilter Jun 03 '20 at 12:10
  • I don't understand why `eval` would be needed in this case. – user1934428 Jun 03 '20 at 12:39
  • So it can handle commands like `ls -l P10*`, where `*` has to be interpreted correctly. – alanwilter Jun 03 '20 at 13:18
  • 1
    I found the reason for while `!!` is not working in my `zsh`. The complete explanation is [here](http://zsh.sourceforge.net/Doc/Release/Options.html). My `.zshrc` had a line `unsetopt BANG_HIST` so to keep compatibility with legacy `ksh` scripts where I used to work. I probably got this from someone there and failed to comment on it. Removing it and `!!` does work now. But in the end, the best solution I found was cited in a comment [here](https://stackoverflow.com/questions/17245614/repeat-last-command-with-sudo) and it's [thefuck](https://github.com/nvbn/thefuck). – alanwilter Jun 03 '20 at 13:37