I aliased sudo
to please
with a space:
$ alias please='sudo '
$ please ll
I have tried this in Fish, but it doesn't work:
$ alias please='sudo '
$ please ll
sudo: ll: command not found
I aliased sudo
to please
with a space:
$ alias please='sudo '
$ please ll
I have tried this in Fish, but it doesn't work:
$ alias please='sudo '
$ please ll
sudo: ll: command not found
The problem here isn't nested aliases. That in itself will work, although (as @muru points out in the comments) somewhat differently than Bash. For instance:
$ alias a ls
$ alias b type
$ b a
a is a function with definition
# Defined via `source`
function a --wraps=ls --description 'alias a ls'
ls $argv;
end
The problem with sudo
in a Fish alias is twofold:
First, an alias is defined for your user, but when you sudo
, you aren't "your user" any more. The fish configuration inside sudo
is that of the root
user. Unfortunately, the elegant Bash solution of appending a "space" doesn't work for Fish.
The Bash "trailing space" workaround of expanding the second alias before passing it to the first, via alias please='sudo '
isn't available in Fish. For instance, in the preceding example, in Bash you could use alias b='type '
to force expansion of a
to ls
and run the type
command on the result rather than the alias.
This is, IMHO, definitely one area where Bash has a (much) cleaner solution than Fish.
There are a few possible workarounds for Fish, but I think they are all rather "hacky", even my own.
First, as I mention in [this Stack Overflow answer], you can define your sudo
alias as follows:
function please --wraps=sudo --description 'alias please sudo'
if functions -q -- "$argv[1]"
set cmdline (
for arg in $argv
printf "\"%s\" " $arg
end
)
set -x function_src (string join "\n" (string escape --style=var (functions "$argv[1]")))
set argv fish -c 'string unescape --style=var (string split "\n" $function_src) | source; '$cmdline
command sudo -E $argv
else
command sudo $argv
end
end
It would probably take me a bit to remember exactly how I arrived at that, which is why I left a commented version with the explanation here.
While you might consider defining the alias in the root user's Fish config, note that sudo
only runs external commands, so it still won't run aliases this way, unless you ask a new fish
process to run it. E.g.:
$ sudo -s
$ alias -s ll "ls -l"
funcsave: wrote /root/.config/fish/functions/ll.fish
$ exit # back to normal user
$ sudo fish -c "ll"
$ sudo ll
sudo: ll: command not found
$ sudo fish -c "ll -n /"
total 1436
lrwxrwxrwx 1 0 0 7 Apr 23 2020 bin -> usr/bin
drwxr-xr-x 2 0 0 4096 Apr 23 2020 boot
...
please
function here might be what OP needs. But the initial example I think isn't quite what's expected. If I were expecting the bash behaviour, taking alias a='ls '
alias b='type '
, the output should be ls is /usr/bin/ls
. The behaviour you show would be that of alias b=type
, for which bash would say a is aliased to `ls '
, like fish
here says a is a function...
.
– muru
Apr 22 '22 at 21:45
sudo
case, but (a) aliases are tied to the user config, and (b) we'll need global abbreviations (not yet implemented) for it to work withabbr
. – NotTheDr01ds Apr 22 '22 at 18:37