11

I want to be able to run a command, it fails cause it doesn't have proper permissions. Then I can write "please" to sudo the command I just ran.

Here's what I want to do in the terminal:

$ run command
"you don't have access to do that"
$ please
"ran successfully"

I saw that !! will grab the previous command, so I thought I could use that, but I can't get it to work.

my please.sh shell script looks like this, but I can't get any of these to work. It just says "command not found !!" and prints out the sudo usage.

#!/bin/zsh

#sudo !!
#sudo `!!`
sudo $(!!)
3
  • Does it work without the script? If you just run sudo !! does it run as expected? I think !! may just be a bash alias, so it may not work in zsh Jul 19, 2012 at 1:07
  • 3
    AFAIK, history expansion (!! and others) only works in interactive shells and not in scripts.
    – Thor
    Jul 19, 2012 at 1:16
  • sudo !! in interactive mode almost works as expected. when I pressed enter it would replace !! with the previous command. then i had to press enter again to run it.
    – jb.
    Jul 19, 2012 at 2:53

2 Answers 2

35

Add to your .zshrc:

alias please='sudo $(fc -ln -1)'
4
  • Works a treat, seems better than above accepted answer for ease of use. Aug 22, 2015 at 11:11
  • 3
    For the curious: fc stands for fix command. The documentation is here.
    – dshepherd
    Jan 6, 2016 at 10:16
  • Thank you! I know this is AskUbuntu, but I used this on OSX to copy my last command to the system clipboard: alias lastcmd="fc -ln -1 | pbcopy" I believe this should (?) work on Ubuntu: alias lastcmd="fc -ln -1 | xclip -selection clipboard.
    – HellaMad
    May 18, 2016 at 7:00
  • Note that if the previous command you are rerunning contained an alias, you may have to define that alias in .zshenv so that it is available in the subshell.
    – xdhmoore
    Sep 17, 2020 at 20:44
6

You cannot use !! in a shell script, as you cannot access the parent shell in a child shell. Though I recommend using sudo !!, if you really want to make a BASH script, you would have to use .bash_history, like so:

#!/bin/bash
sudo `cat $HOME/.bash_history | tail -n1`

It is definitely NOT a perfect solution, but it should do the trick. If you are using ZSH, this will not work, as ZSH does not output to .bash_history (of my knowledge). UPDATE: Here is a version that should work with ZSH:

#!/usr/bin/zsh
. $HOME/.zshrc
sudo `cat \`readlink -f $HISTFILE\` | tail -n1`

Hope this helps!

If you don't understand the script, it simply runs the last command entered in BASH with sudo.

3
  • ok. I'm using zsh though. is there any equivalent for .bash_history in zsh?
    – jb.
    Jul 19, 2012 at 2:51
  • Now that I look, yes, there is a version that should work. I haven't tested it yet though.
    – MiJyn
    Jul 19, 2012 at 23:45
  • 1
    Don't read the bash history file directly. Use the fc or history built-ins. By default, the $HISTFILE is not updated until you log out of bash.
    – Steven K
    Sep 30, 2014 at 22:52

You must log in to answer this question.

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