Aliases, whether you use Bash, ZSH or any other shell, are a really easy way to improve your day to day workflow. The basic syntax for aliases is the following:
alias l='ls -al'
This syntax is pretty simple, but is unfortunately very limited in what you can do:
- it doesn't let you handle custom parameters. What if you want to add a custom
--json
parameter tocurl
that expands to--header "Content-Type: application/json"
? - it doesn't let you add subcommands. What if you want to create a custom
docker sh
subcommand that expands todocker exec -it container_name sh
?
Well the cool thing is that you can do all of that, simply using shell functions! Yep, nothing new in here, but using functions to create advanced aliases is often disregarded or forgotten.
Anyway, let's see how to implement the above aliases!
Note: The following snippets will use Bash specifically. It should not be too hard to adapt them to other shells.
Add a custom flag to a command
When using curl
, I often want to send JSON payloads. To do so, the Content-Type: application/json
header is usually required by servers. I'd like to be able to write this:
curl --json -d '{"foo": "bar"}' https://example.com/endpoint
instead of this:
curl -H 'Content-Type: application/json' -d '{"foo": "bar"}' https://example.com/endpoint
You can add this custom flag with the following function:
curl() {
local -a args;
for arg in "$@"; do
case $arg in
--json) args+=("-H" "Content-Type: application/json") ;;
*) args+=("$arg") ;;
esac
done
command curl "${args[@]}"
}
So what happens in this snippet?
- At first, we create a new
curl
function. It will wrap the already existingcurl
command and we'll be able to modify how it's called. - Then, we loop on all the arguments passed to the command, and add them to a new
args
array. - When we encounter the
--json
argument, we push the new arguments"-H" "Content-Type: application/json"
to our list instead. - Finally, we call the original
curl
command with the modified list of arguments. Make sure to usecommand
in front ofcurl
to avoid calling the alias function recursively.
And that's it! There's no magic in here, we just cleverly use some basic Bash building blocks.
Using the same techniques, we can easily decide to replace the -d
argument with --json
to get the following final command:
curl --json '{"foo": "bar"}' https://example.com/endpoint
This is left as an exercise to the reader.
Add a custom subcommand to a command
When using docker
, it's common to get into a container to explore the file hierarchy. The command to do this operation is the following:
docker exec -it container_name sh
I want to write this instead:
docker sh container_name
The principle is the same as above, you can write a function like this:
docker() {
if [ $# -ge 1 ]; then
case "$1" in
"sh")
if [ $# -ne 2 ]; then
echo '"docker sh" requires 1 argument.'
echo
echo "Usage: docker sh NAME|ID"
echo
echo "Start an interactive shell inside a running container"
return 1
fi
command docker exec -it "$2" bash
;;
esac
fi
command docker "$@"
}
The only difference with the previous script is that we create a new sh
subcommand that we implement ourselves.
We could trivially implement additional flags (--help
, --bash
, etc.) to our new subcommand following the same patterns.
This article contains no novel concepts, but will helpfully help you get creative in creating more specific aliases to your workflows.
The main thing to remember is the existence of the command
built-in that allows you to declare a function with the same name as an existing command, and still be able to use the original command.
Top comments (0)