• We had to restore from a backup today after a failed software update. Backup was from 0000 EDT and restored it at 0800 EDT so we lost about 8hrs. Today is 07/20/2024. More info here.

Understanding and using the alias Command

Jarret B

Well-Known Member
Staff member
Joined
May 22, 2017
Messages
352
Reaction score
397
Credits
12,511
Back in the old days of computers, I remember running DOS 3.3. I had a folder named 'batch' that included all the 'shortcuts' to perform commands by a batch file. Of course, the 'batch' folder was in my environment variable 'PATH'. So, no matter what directory I was in, I could run one of the batch file that acted as a shortcut.

In this same manner, we can use an 'Alias' to shorten a set of command instructions to a single command word.

Using aliases allows you to shorten long command strings into a single word and save time on your system.

Basic Use

You may need to see what aliases you already have on your system. The best way is to list your existing aliases:

Code:
alias

The command 'alias' with no parameters just provides a list of existing aliases. Figure 1 shows an example of the output.

Figure 1.JPG

FIGURE 1

You can also use the parameter '-p' to print the list of aliases, which gives the same result.

An alias is 'alias short name = command string'. Let's make an example. For instance, if we want the 'ls' command to show all the files, we can create an alias for 'ls' to always be 'ls -a'. We can use the command:

Code:
alias ls="ls -a"

Now, when we type 'ls', we get a listing of all files and folders, even the hidden ones.

If we reboot the system or even close the terminal and re-open it, the alias is gone.

Making an Alias Permanent

If we want an alias to persist after rebooting or closing and opening the terminal, we need to add the alias to the environment.

Within the '~/.bashrc', there is a section:

Code:
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
     . ~/.bash_aliases
fi

We can add the alias commands to the '.bashrc' file or create and add the commands to '~/.bash_aliases'.

No matter the file you use, place the complete command in the file. Such as 'alias ls-"ls -a"'. You can close and re-open the terminal, then enter 'alias' to make sure your additions are active.

The example I gave is short, but we can lengthen the alias to something like:

Code:
alias up='sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y && sudo apt dist-upgrade -y'

Not only does the command 'up' perform an update of the repository lists, but performs an upgrade with 'yes' as the default answer to any queries by the system. It also performs an 'autoremove' of unneeded packages, again answering 'yes' to any queries. Finally, the aliased command will perform distribution upgrades as well. You can, of course, change the order of the commands as you need.

Keep in mind that aliases can also be case-sensitive. An alias of 'lsa' differs from 'LSA' and even 'LSa'.

Issues

Be sure that you do not alias an existing command that you do not want to lose. For example, we previously changed the 'ls' command to show even hidden files, but we may not want hidden files displayed every time we list files.

To prevent this from happening, you can type a command you want to create and see if it exists. If it doesn't exist, then an error will occur. You can also use the command 'type' followed by the command you want to alias, such as 'type up'. The response will let you know if the command 'up' is being used at all.

Removing an Alias

If you did not add the alias to the '~/bashrc' file, then you can remove the alias from the current environment. If the alias is permanent by being in the '~/.bashrc' file, you can remove it from the current terminal environment, but when you restart the terminal, it’s read from the file when the terminal starts again.

To remove an alias from the current environment, use the command:

Code:
unalias <alias>

So, we can use the command 'unalias ls' to remove the 'ls' command we set up. Or even 'unalias up'. You can then type 'up' and it shouldn't work. Close the terminal and restart it, and the 'up' command should work again.

If you include the command in the '~/.bashrc' file or another file, like '~/.bash_aliases', you need to remove the line from the file. The terminal needs to be closed and restarted so the changes will take effect.

If you want to remove all aliases from the current environment, then use the command 'unalias -a'.

Other Possibilities

An alias can call a script. Here, you can have powerful scripts being called that are included in an alias.

This can be especially useful if the script is called within a group of commands that you usually run. Now, an alias can run all the commands in one, including the script.

Useful Examples

From the old DOS days, you used to do a 'cd..' to go up a folder in the tree, but in Linux, there must be a space. So you can use the alias:

Code:
alias cd..="cd .."

Another possibility is to use an alias for 'edit' to your preferred editor:

Code:
alias edit=nano

Just make sure after changing the 'bashrc' files, exit the terminal and restart it.

Checking Individual Aliases

Let's say we set an alias for the command 'edit' and used it with our favorite editor.

We can check the alias with the command 'alias' followed by the command, such as:

Code:
alias edit

The result should be the command used to set up the alias for 'edit':

Code:
alias edit='nano'

If an alias isn't working the way we thought, we can see the command to verify there are no typos in setting up the alias.

Conclusion

Alias is a great way to shorten multiple commands into one. You can set the aliases to include specific parameters so you do not have to type them every time.

If needed, keep the alias file handy to put onto new systems so your aliases are always available.
 
Last edited:


Also, one thing you've overlooked is the concept of "escaping" aliases. Which is done by prefixing a command with a backslash (\).

This allows us to "escape" any aliases that may have been set for a particular command. Preventing any defined aliases from sending extra, unwanted parameters to a command. That way the command will only use the parameters that we specify.

So for example, I mostly use grep to search for words, or patterns in the source code of any pieces of software I work on.
In my .bashrc I have an alias set up for grep, to display the file-name and the line-numbers of matches and to highlight any matches in colour, so they can easily be distinguished in the output.
So my alias for grep looks like this:
Bash:
alias grep='grep -Hn —color'

Which is great for when I’m searching for a particular variable in a codebase.
I’ll typically enter something like:
Bash:
grep -R someVariable /path/to/codebase/
In the above, I’ve added the -R flag, which is a recursive search.

Because we have an alias set, Bash will use substitution to expand the above grep to use the alias. So the command I entered above will effectively be interpreted by the shell as:
Bash:
grep -Hn —color -R someVariable /path/to/codebase/

Then grep conveniently shows me all places in the codebase where someVariable is used. Displaying the filename, the line-number and the matching line, with coloured output, to make it more readable.

That’s great for when I’m doing one of my typical searches. But if I’m using grep inside a script, or even in a bash one-liner, the -Hn switches used in the alias could pollute the output in an undesirable way.

So for example, I want to use a bash one-liner which searches the output of a command like ps, to find any running instances of a particular process (let's say bash?!) and then use awk to process the output, to re-order the columns.

I'm going to use ps -aux to list all running processes.
With those flags active, the columns in the output from ps will be:
USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND

Now lets say I want to see the output listed as: COMMAND PID USER.
Looking at the fields listed above, I want to output fields 11, 2 and 1.
So after using ps to list processes and using grep to filter out and find processes that contain bash (we'll also filter out the process containing our greps ). And we'll use awk to re-order the output to show the specified columns.

It's worth noting at this point that if the command-string in field 11 contains any spaces, the rest of the command will be output as additional fields. So to capture the entire command string, we need to output field 11 and any fields that follow it. Which will complicate our awk command a little.
In awk, I'll use a for loop to output columns 11 onwards using printf, before using another printf to output columns 2 and 1 and a newline to end the line.

So I enter the following command:
Bash:
ps -aux | grep bash | grep -v grep | awk '{for(i=11; i<NF; i++) printf $i " " ; printf $2 " " $1 "\n"}'
In the above, the ps -aux command gets our list of processes, the two grep's filter the output to show us all lines that contain the word bash and also hides any lines containing grep. And then awk will re-order the output to show us the entire command string (fields 11 onwards), followed by the PID and the User.

But after entering the above one-liner, my output looks like this:
10:51 0:00 /bin/bash /home/jason/bin/setrt input):1:(standard (standard
10:51 0:00 /bin/bash input):2:(standard (standard
Oh no! Why has it done that?! Have I messed up something in the for loop in awk?

No, the problem is actually because I have an alias set for grep.
Here's my alias again:
Bash:
alias grep='grep -Hn --color'

So in the really long bash one-liner above. Because of my grep alias, the two grep commands were substituted for the alias and the command was interpreted by the shell as:
Bash:
ps -aux | grep -Hn --color bash | grep -Hn --color -v grep | awk '{for(i=11; i<NF; i++) printf $i " " ; printf $2 " " $1 "\n"}'

So because of the extra parameters in the alias, grep is adding extra columns to the output. It's adding the file-name "standard input" and it's also outputting the line-numbers. So for the purposes of this one-liner - the alias is polluting the output of the commands in an undesirable way, by adding extra columns and completely messing things up!

So how do we get around this problem? We could try to edit the one-liner to re-number the the columns in the awk command to account for and ignore the extra columns added by grep. Or we could simply "escape" the alias for grep, preventing the alias from adding extra parameters, thereby preventing the extra columns from polluting the output of the other commands.

Being extremely lazy, I don't want to mess around and try to re-number the columns in the awk part of the one liner. It's much simpler to escape the aliases for grep. So that's what I'll do:
e.g.
Bash:
ps -aux | \grep bash | \grep -v grep | awk '{for(i=11; i<NF; i++) printf $i " " ; printf $2 " " $1 "\n"}'

In the above we've "escaped" the alias for grep by prefixing both of the grep commands with a backslash. This causes the shell to ignore any aliases for the command that follows the backslash (in this case grep). So the only parameters that are sent to the command are the parameters that we send it. No substitution is performed to replace the command with the alias. So our one-liner is interpreted exactly as we typed it.

Now the output is:
/bin/bash /home/jason/bin/setrt 7371 jason
/bin/bash 13610 jason
Much better!

As a general rule of thumb - whenever I write a bash one-liner, or script that uses a command that users typically have aliases set-up for (ls and grep are probably the most common) - I will always prefix the command with a backslash, in order to "escape" any potential aliases and prevent them from adding unwanted extra parameters and polluting the output.

If you spend a lot of time in the terminal, aliases are awesome. They can save us from a lot of extra typing. But as awesome as they are - sometimes they get in the way and you need to "escape" them!
 
Last edited:
I actually have a very similar alias to do my updates, although I still like to confirm what's going to be removed/upgraded so I leave the "-y" out.
 
Also, one thing you've overlooked is the concept of "escaping" aliases. Which is done by prefixing a command with a backslash (\).

This allows us to "escape" any aliases that may have been set for a particular command. Preventing any defined aliases from sending extra, unwanted parameters to a command. That way the command will only use the parameters that we specify.

So for example, I mostly use grep to search for words, or patterns in the source code of any pieces of software I work on.
In my .bashrc I have an alias set up for grep, to display the file-name and the line-numbers of matches and to highlight any matches in colour, so they can easily be distinguished in the output.
So my alias for grep looks like this:
Bash:
alias grep='grep -Hn —color'

Which is great for when I’m searching for a particular variable in a codebase.
I’ll typically enter something like:
Bash:
grep -R someVariable /path/to/codebase/
In the above, I’ve added the -R flag, which is a recursive search.

Because we have an alias set, Bash will use substitution to expand the above grep to use the alias. So the command I entered above will effectively be interpreted by the shell as:
Bash:
grep -Hn —color -R someVariable /path/to/codebase/

Then grep conveniently shows me all places in the codebase where someVariable is used. Displaying the filename, the line-number and the matching line, with coloured output, to make it more readable.

That’s great for when I’m doing one of my typical searches. But if I’m using grep inside a script, or even in a bash one-liner, the -Hn switches used in the alias could pollute the output in an undesirable way.

So for example, I want to use a bash one-liner which searches the output of a command like ps, to find any running instances of a particular process (let's say bash?!) and then use awk to process the output, to re-order the columns.

I'm going to use ps -aux to list all running processes.
With those flags active, the columns in the output from ps will be:
USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND

Now lets say I want to see the output listed as: COMMAND PID USER.
Looking at the fields listed above, I want to output fields 11, 2 and 1.
So after using ps to list processes and using grep to filter out and find processes that contain bash (we'll also filter out the process containing our greps ). And we'll use awk to re-order the output to show the specified columns.

It's worth noting at this point that if the command-string in field 11 contains any spaces, the rest of the command will be output as additional fields. So to capture the entire command string, we need to output field 11 and any fields that follow it. Which will complicate our awk command a little.
In awk, I'll use a for loop to output columns 11 onwards using printf, before using another printf to output columns 2 and 1 and a newline to end the line.

So I enter the following command:
Bash:
ps -aux | grep bash | grep -v grep | awk '{for(i=11; i<NF; i++) printf $i " " ; printf $2 " " $1 "\n"}'
In the above, the ps -aux command gets our list of processes, the two grep's filter the output to show us all lines that contain the word bash and also hides any lines containing grep. And then awk will re-order the output to show us the entire command string (fields 11 onwards), followed by the PID and the User.

But after entering the above one-liner, my output looks like this:

Oh no! Why has it done that?! Have I messed up something in the for loop in awk?

No, the problem is actually because I have an alias set for grep.
Here's my alias again:
Bash:
alias grep='grep -Hn --color'

So in the really long bash one-liner above. Because of my grep alias, the two grep commands were substituted for the alias and the command was interpreted by the shell as:
Bash:
ps -aux | grep -Hn --color bash | grep -Hn --color -v grep | awk '{for(i=11; i<NF; i++) printf $i " " ; printf $2 " " $1 "\n"}'

So because of the extra parameters in the alias, grep is adding extra columns to the output. It's adding the file-name "standard input" and it's also outputting the line-numbers. So for the purposes of this one-liner - the alias is polluting the output of the commands in an undesirable way, by adding extra columns and completely messing things up!

So how do we get around this problem? We could try to edit the one-liner to re-number the the columns in the awk command to account for and ignore the extra columns added by grep. Or we could simply "escape" the alias for grep, preventing the alias from adding extra parameters, thereby preventing the extra columns from polluting the output of the other commands.

Being extremely lazy, I don't want to mess around and try to re-number the columns in the awk part of the one liner. It's much simpler to escape the aliases for grep. So that's what I'll do:
e.g.
Bash:
ps -aux | \grep bash | \grep -v grep | awk '{for(i=11; i<NF; i++) printf $i " " ; printf $2 " " $1 "\n"}'

In the above we've "escaped" the alias for grep by prefixing both of the grep commands with a backslash. This causes the shell to ignore any aliases for the command that follows the backslash (in this case grep). So the only parameters that are sent to the command are the parameters that we send it. No substitution is performed to replace the command with the alias. So our one-liner is interpreted exactly as we typed it.

Now the output is:

Much better!

As a general rule of thumb - whenever I write a bash one-liner, or script that uses a command that users typically have aliases set-up for (ls and grep are probably the most common) - I will always prefix the command with a backslash, in order to "escape" any potential aliases and prevent them from adding unwanted extra parameters and polluting the output.

If you spend a lot of time in the terminal, aliases are awesome. They can save us from a lot of extra typing. But as awesome as they are - sometimes they get in the way and you need to "escape" them!
JasKinsasis, that is one heck of a post! I'm not nearly that complex :)
 

Staff online

Members online


Top