I see this pattern every once in a while, especially in questions about Bash prompt customization.
alias f='_ () { useful code; }; _'
I can see no reason at all to create an alias here. The obvious refactoring
f () { useful code; }
which avoids declaring an alias altogether, and simply defines the function once and for all, seems simpler, more understandable, less brittle, and more efficient. (In case it's not obvious, the alias ends up redeclaring the function every time you invoke the alias.)
For example, Make a Bash alias that takes a parameter? has several answers which exhibit this technique. bash script to run lftp with ftp path is a question which has code like this in a question about the actual functionality inside the function, and the OP doesn't explain why even though I prodded gently.
Is this just plainly an antipattern, or is there an actual reason to do this? Under what circumstances would this design make sense?
This is not about aliases with a space after them, or about code obfuscation (the examples I have found are generally entirely readable, apart from this mystifying technique).
From OSP dictionary we would define Function alias as the rules that promote the usage of the function (Java/SQL) to the users (non-developers ) who maintain business rules (Decision tree, Decision table, When) or create/configure reports in Production.
Functions can be used in scripts or in the console, but are more often used in scripts. Contrary to aliases, which are just replaced by their value, a function will be interpreted by the bash shell. Functions are much more powerful than aliases. They can be used to build very complex programs.
In computing, alias is a command in various command-line interpreters (shells), which enables a replacement of a word by another string. It is mainly used for abbreviating a system command, or for adding default arguments to a regularly used command.
Here are my 2 cents on this and it represents my personal opinion as well as understanding on the topic.
Example:
alias kgps='kubectl get pods --all-namespaces | grep '
This works great and I can search my kubernetes pods. Now for deleting these pods, I need to pass the same parameter but in between the command, so I use an alias with a function inside
alias kdp="_(){ kubectl get pods --all-namespaces | grep \$1 | awk '{print \$2}' | xargs kubectl delete pod; }; _"
So most of my shortcut commands are possible to execute through aliases
and only few which needs such things I use aliases with functions.
Now there are few differences between aliases and functions which I would like to highlight
Aliases can override system commands much more easily compared to functions
If I need to override ls
, I can do that much easier with alias
alias ls='ls -altrh'
While a function equivalent of the same would be like below
ls() { command ls -altrh "$@";} ls() { /bin/ls -altrh "$@";}
Aliases intention is mostly for shortcuts
Aliases are majorly used to create shortcut commands while functions are used for a lot of things, complex combinations of commands, auto-completion, bash prompts
Aliases are easier to manage
Run alias
command you get a list of currently active aliases
$ alias .... vs='vagrant ssh' vu='vagrant up' vus='vu && vs' ....
To get the list of functions we need to use declare -f
or another similar command
$ declare -f | wc -l 8226 $ alias | wc -l 217
Now if I post a partial output of declare -f
I get
$ declare -f ... vi_mode_prompt_info () { return 1 } virtualenv_prompt_info () { return 1 } work_in_progress () { if $(git log -n 1 2>/dev/null | grep -q -c "\-\-wip\-\-") then echo "WIP!!" fi } zle-line-finish () { echoti rmkx } zle-line-init () { echoti smkx } zsh_stats () { fc -l 1 | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl | head -n20 }
As you can see there are lots of functions which are used but are not relevant to me. While the alias
command gives me a very concise output and I can easily see what all is there. In my case, 100% of them are shortcut commands
Escaping aliases and functions syntax is different for system commands
To escape a defined alias you need to prefix it with \
while for functions
you need to either use command <originalcommand>
or absolute path of the command /bin/originalcommand
Aliases have higher priority over function
Look at the below example
alias ls='echo alias && ls' $ ls() { /bin/ls -al } alias $ ls alias total 23173440 drwxrwxr-x+ 255 tarunlalwani staff 8160 Jul 30 22:39 . drwxr-xr-x+ 113 tarunlalwani staff 3616 Jul 30 23:12 .. ...
As you can see when we run the ls
command, first the alias is used and then the next ls
is calling the function.
This becomes also a way of wrapping an exiting function with the same name and re-using the original function inside as well, which can only be done using alias
and promotes the format in the question
I found this answer too [U&L] In Bash, when to alias, when to script, and when to write a function? which explains the benefit of defining a function in an alias.
The benefit of doing so over declaring a function is that your alias cannot be simply overwritten by source-ing (or using
.
) a script which happens to declare a same-named function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With