This is an illustration of the difference between authentication and authorization.
Sudo is primarily a tool for authorization. Its job is to determine whether you are allowed to execute a command with elevated privileges, and if you are, to execute that command. An entry like
bruno ALL = (ALL): ALL
in the sudoers
file allows the user bruno
to execute any command with any privilege.
In order to apply this rule, Sudo needs to know that the user invoking it is indeed bruno
. In principle, it can rely on the system's authentication mechanism: if you can run commands as bruno
, it means you've already authenticated as bruno
. However, since using Sudo can have major consequences, Sudo requires some extra authentication: you need to type your password again, sometimes. This means that if you've left your console unattended and a passer-by gets to run command as bruno
, they won't be able to use Sudo: they might be able to damage your account, but not the rest of the system.
Another advantage of requesting a password is that it alerts you that something unusual is taking place. For example, an application cannot silently call sudo
: it would need to ask you for your password, and an unexpected password prompt would alert you that something bad is taking place.
In practice, asking for a password each and every time you run Sudo would be annoying. Therefore the default behavior is to compromise: ask for a password every few minutes. This way, a passerby or application can cause harm by running sudo
only if you've done it within the last few minutes.
I just discovered the reason, and it was a collection of circumstances:
First of all, I don't know exactly why, but sudo
was not grabbing the HOME
environment variable properly and used the one of the regular user, so it read the .vimrc
from /home/user/.vimrc.
In order to see this, I issued:
user@hostname:~$ sudo bash
[sudo] password for user:
root@hostname:/home/user# echo $HOME
/home/user
Second, I have folding persistence enabled in my user's vimrc file in order to store cursor position:
au BufWinLeave * mkview
au BufWinEnter * silent loadview
This makes that every time a file is edited, a properties file is created inside $HOME/.vim/view
folder.
In my case, it looks like I tried to edit the file without sudo
the first time, so the folding file was created as regular user's:
user@hostname:~$ ll .vim/view/ | grep thunderbird.sh
-rw-rw-r-- 1 user user 2650 Aug 20 15:56 =+usr=+lib=+thunderbird=+thunderbird.sh=
Since the root took /home/user
as $HOME
, the same folding file was (wrongly) used when I issued sudo vim
, and for some reason that I ignore, probable related to vim internals, if the folding file is not owned by the editing user, the edited file is opened in ReadOnly mode.
So, I realized that if I removed the file /home/user/.vim/view/=+usr=+lib=+thunderbird=+thunderbird.sh=
and then tried to edit using sudo vim,
I had no problems at all.
So, at the end of the story, in order to fix this situation I just edited /etc/sudoers
and added this line:
Defaults always_set_home
Now everything works as expected and I can use sudo
reliably again.
Best Answer
I think using history completion is a much more universal way to do this
Most shells have some shortcut for the previous command. That one works in bash and zsh. There are various ways you can do substitution, but usually these are best left for removing or changing bits, if you want to expand it, just grabbing the whole thing is the simplest way. You can add whatever you like before and after the !! to expand on the previous command.
Edit: The original question was about prepending to the previous command which the above covers nicely. If you want to change something inside it as the commentor below the syntax would go like this:
...where 'search' is the string to match against and replace...well you get the idea.