8

Frequently in Terminal (though I fully expect any answer will work in bash and most others), I type some command, and then get some sort of permission error due to missing sudo.

Okay, so press 'up', hold/hammer 'left', type sudo and hit 'enter'.

It's annoying. More so the longer the command was.

Note that missing sudo is worst case; a typo nearer the beginning than end is similarly annoying.

What I would like, is a way to perform a sort of 'up and home' keystroke. Actually, perhaps those two strokes will do it - but my Macbook keyboard doesn't have Home, so I cannot try.

Bonus points for a way to insert sudo and hit 'enter' auto-magically too, say by CMD+Shift+S.


Can this be done, or am I dreaming?

0

4 Answers 4

16

Simply use UP and CTRL-A.

Both !sudo and sudo !! function easy. With a difference:

  • sudo !! will execute the last command taken from the history with sudo in the beginning.

  • !sudo will execute the last command in the history that started with sudo.

  • Usually CTRL-A brings you at the beginning of the line in a linux terminal and CTRL-E to the end.
    If you want you can continue to use your strategy. You have only to discover the shortcut of your system. You can find a list of shortcuts in graphic and text environment e.g. here.

Only a warning: sudo !! and !sudo function really fast and you have no visual control of the line you are running as superuser. This can result harmful sometimes. Specially if you incur in a missprint.

Let's we do a dramatic example:

cd $HOME/Directory_To_Delete  # You go to delete what is inside a directory
rm -rf . ; cd ..              # You do it and go up of one
 apt-get update               # Note the space in the beginning of the line  
sudo !!                       # Gone!! Now you realize you never really wanted 

Too late you just erased your home directory and all the subfolders !!.

When you write a command with a space as a first character it's possible that it will not finish in the history. This depend from the value of the variable $HISTCONTROL. If the list of its values includes ignorespace (or ignoreboth) the lines which begin with a space character are not saved in the history list. So with sudo !! you will execute the last command before.

You can imagine similar situation with !sudo, it will execute the last command starting with sudo recorded in the history, but if the last that you remember was starting with a space... now you know you will use another.

Last note: less is dramatic your error more it can be devious because it can pass without that you notice... and you will risk to be called to pay all the interests of a bill that you cannot remember.


Update (Bash is great):
with recent versions of Bash it is possible to fix this dangerous behaviour with the following command that I suggest to put in ~/.bashrc file:

shopt -s histverify

From man bash you can read

If the histverify shell option is enabled and readline is being used, history substitutions are not immediately passed to the shell parser. Instead, the expanded line is reloaded into the readline editing buffer for further modification.

So you can read, and modify when needed, the command that you will execute.
Since it is not the default setting in many distribution we still have to remember it when we use other accounts.

3
  • 1
    I can't remember whether it's Ctrl+A or Cmd+A, but this shortcut is what I usually use when I used to work on OS X. Note that Ctrl+A gets you to the start of the command like "Home" button and Ctrl+E gets you to the end of the command like "End" button. I'm usually hesitant to use !! especially in combination with sudo, in case it turns out that the previous command isn't what I thought it ought to be.
    – Lie Ryan
    Jul 4, 2014 at 2:19
  • 1
    CTRL+A is right for Mac OS X, I use it all the time. Jul 4, 2014 at 15:03
  • @KenzieTogami Thanks for the confirmation I update the answer.
    – Hastur
    Jul 4, 2014 at 15:44
5

Here are a few common keyboard combinations that many Mac and Linux programs use (not sure which are followed by most Windows apps, though):

  • CTRL-A - Bring the cursor to the beginning of the current line
  • CTRL-E - Bring the cursor to the end of the current line
  • CTRL-Left - Move the cursor back one word
  • CTRL-Right - Move the cursor forward one word
3
  • 1
    Also, the Home and End keys.
    – Bob
    Jul 4, 2014 at 2:55
  • @Bob I did mention those in my OP. Don't exist on Apple keyboards though.
    – OJFord
    Jul 4, 2014 at 7:17
  • @OllieFord Ah, sorry. I kinda skimmed through it.
    – Bob
    Jul 4, 2014 at 7:21
4

Use

sudo !!

The !! will be replaced by the complete previous command.

1
  • You just took all my bonus points in one fell swoop!
    – OJFord
    Jul 3, 2014 at 20:44
3

@WChargin is correct regarding !sudo, so I'm changing my answer...

sudo !! is the correct answer, as many have said.

Just in case, I'm pasting here the following, in regards to the history command, and how that ! command works. I hope this helps.


The history command

The history command can be used to list Bash's log of the commands you have typed:

This log is called the “history”. To access it type:

history n 

This will only list the last n commands. Type “history” (without options) to see the the entire history list.

You can also type !n to execute command number n. Use !! to execute the last command you typed.

!-n will execute the command n times before (in other words !-1 is equivalent to !!).

!string will execute the last command starting with that “string” and !?string? will execute the last command containing the word “string”. For example:

!cd will re-run the command that you last typed starting with “cd”.

commandName !* will execute the “commandName” with any arguments you used on your last command. This maybe useful if you make a spelling mistake, for example. If you typed:

emasc /home/fred/mywork.java /tmp/testme.java 

In an attempt to execute emacs on the above two files this will obviously fail. So what you can do is type:

emacs !* 

This will execute emacs with the arguments that you last typed on the command-line. In other words this is equivalent to typing:

emacs /home/fred/mywork.java /tmp/testme.java

~ The command-line history

3
  • That's not what !sudo does. The event designator !sudo will execute the last command that began with sudo. You're looking for sudo !!—the !! designator expands to the previous command.
    – wchargin
    Jul 4, 2014 at 3:42
  • @WChargin, you are correct :) Thanks for pointing that out. I'm editing my answer.
    – jimm-cl
    Jul 4, 2014 at 14:32
  • Good edit. References are always good.
    – wchargin
    Jul 4, 2014 at 14:33

You must log in to answer this question.

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