I've been using bash for a decade or so and have gotten used to being able to type !$ to repeat the last argument, e.g.:

$ mkdir foo
$ cd !$
cd foo

(That last line is printed by the shell to tell you what your command evaluated to). Likewise I often to the following:

$ make_sandwich
-bash: make_sandwich: Permission denied
$ sudo !!
sudo make_sandwich

I'm really liking the fish shell, but my muscle memory is pretty established. Is there an equivalent in fish? Can I configure fish to use the same commands?


Alt-Up arrow gives you the last argument from the previous command. Subsequent pushes cycle throught prior arguments.

I haven't found a satisfactory equivalent to !!, except Up then Ctrl-A


I found this perfect answer on the fish-users mailing list:

function bind_bang
    switch (commandline -t)[-1]
        case "!"
            commandline -t $history[1]; commandline -f repaint
        case "*"
            commandline -i !

function bind_dollar
    switch (commandline -t)[-1]
        case "!"
            commandline -t ""
            commandline -f history-token-search-backward
        case "*"
            commandline -i '$'

function fish_user_key_bindings
    bind ! bind_bang
    bind '$' bind_dollar

Further discussion on fish's github wiki

  • 1
    That is awesome! You should consider editing the top answer to include this... – user1480704 Aug 4 '16 at 15:33
  • 2
    I created ~/.config/fish/config.fish and pasted this. It worked great after restarting fish. – Katu Nov 20 '16 at 10:56
  • I feel like this answer and the current top one mentioning alt + up should be combine. This one is great because it's exactly the solution that the question is asking but the current top answer is because it's a more canonical fish way of doing it. – klvs Apr 28 '20 at 3:59

sudo !! (or sudo bang bang) is one of my most oft used commands. I'm still using just plain old bash that has it just fine. Sorry to hear that fish doesn't implement it correctly. A little googling and I found this:

function sudo
    if test "$argv" = !!
        eval command sudo $history[1]
        command sudo $argv

There are a lot more options over on the thread here: https://github.com/fish-shell/fish-shell/issues/288

  • where do I have to enter that code? entering that into fish and then "sudo !!" returns some error lines with "source: Error while reading file '-'" – Benedikt S. Vogler Sep 23 '16 at 14:31

I had the same problem as you, and I fixed by using oh-my-fish (it's a plugin manager for fish shell) https://github.com/oh-my-fish/oh-my-fish. You can install it with this command :

curl -L https://get.oh-my.fish | fish

Then install the plugin bang-bang with this command :

omf install bang-bang 

In Fish Shell you can use the binding __fish_prepend_sudo (which is ALT+s per default) to prepend the currently present command with sudo :

$ make sandwich▎ 


$ sudo make sandwich▎

You can cycle through the arguments of previous commands using the binding history-token-search-backward (which is ALT+., as in Bash; but ALT+ and ALT+ can be used as well):

$ mkdir foo
$ rmdir ▎


$ rmdir foo▎

All of Fish Shell's binding can be viewed by executing fish_config and navigating to the "binding" tab.

  • This is my preferred method as well, but as a heads-up, I think you reversed your history-token-search-backward and __fish_prepend_sudo when you added those during the edit. I don't want to make another edit myself, since that would violate the StackExchange "don't change the meaning in an edit" rule. So can you double-check your text and intent there? Thanks! – NotTheDr01ds Jan 6 at 22:26
  • Thank you @NotTheDr01ds. That was helpful. I edited my post accordingly and fixed the mixup. – jnns Jan 7 at 13:56

If you use !! only in the context of sudo !!, you can define a keybinding to ^s (CTRL+s) which prepends sudo to your command:

function prepend_command
  set -l prepend $argv[1]
  if test -z "$prepend"
    echo "prepend_command needs one argument."
    return 1

  set -l cmd (commandline)
  if test -z "$cmd"
    commandline -r $history[1]

  set -l old_cursor (commandline -C)
  commandline -C 0
  commandline -i "$prepend "
  commandline -C (math $old_cursor + (echo $prepend | wc -c))

This allows to type in any command and prepend sudo while typing or like in your case as a substitution of sudo !!

See the Ahti's comment on the github discussion

  • 1
    For those reading several years later, Fish has now incorporated this (or a similar) function by default with the Alt+s keybinding. See @jnns's answer for more details. – NotTheDr01ds Jan 6 at 22:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.