Some time ago, the Fedora Magazine has published an article introducing ZSH — an alternative shell to Fedora’s default, bash. This time, we’re going to look into customizing it to use it in a more effective way. All of the concepts shown in this article also work in other shells such as bash.
Alias
Aliases are shortcuts for commands. This is useful for creating short commands for actions that are performed often, but require a long command that would take too much time to type. The syntax is:
$ alias yourAlias='complex command with arguments'
They don’t always need to be used for shortening long commands. Important is that you use them for tasks that you do often. An example could be:
$ alias dnfUpgrade='dnf -y upgrade'
That way, to do a system upgrade, I just type dnfUpgrade instead of the whole dnf command.
The problem of setting aliases right in the console is that once the terminal session is closed, the alias would be lost. To set them permanently, resource files are used.
Resource Files
Resource files (or rc files) are configuration files that are loaded per user in the beginning of a session or a process (when a new terminal window is opened, or a new program like vim is started). In the case of ZSH, the resource file is .zshrc, and for bash it’s .bashrc.
To make the aliases permanent, you can either put them in your resource. You can edit your resource file with a text editor of your choice. This example uses vim:
$ vim $HOME/.zshrc
Or for bash:
$ vim $HOME/.bashrc
Note that the location of the resource file is specified relatively to a home directory — and that’s where ZSH (or bash) are going to look for the file by default for each user.
Other option is to put your configuration in any other file, and then source it:
$ source /path/to/your/rc/file
Again, sourcing it right in your session will only apply it to the session, so to make it permanent, add the source command to your resource file. The advantage of having your source file in a different location is that you can source it any time. Or anywhere which is especially useful in shared environments.
Environment Variables
Environment variables are values assigned to a specific name which can be then called in scripts and commands. They start with the $ dollar sign. One of the most common is $HOME that references the home directory.
As the name suggests, environment variables are a part of your environment. Set a variable using the following syntax:
$ http_proxy="http://your.proxy"
And to make it an environment variable, export it with the following command:
$ export http_proxy
To see all the environment variables that are currently set, use the env command:
$ env
The command outputs all the variables available in your session. To demonstrate how to use them in a command, try running the following echo commands:
$ echo $PWD
/home/fedora
$ echo $USER
fedora
What happens here is variable expansion — the value stored in the variable is used in your command.
Another useful variable is $PATH, that defines directories that your shell uses to look for binaries.
The $PATH variable
There are many directories, or folders (the way they are called in graphical environments) that are important to the OS. Some directories are set to hold binaries you can use directly in your shell. And these directories are defined in the $PATH variable.
$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/share/Modules/bin:/usr/lib64/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/usr/libexec/sdcc:/usr/libexec/sdcc:/usr/bin:/bin:/sbin:/usr/sbin:/opt/FortiClient
This will help you when you want to have your own binaries (or scripts) accessible in the shell.
Joao Rodrigues
Aliases can have the same name as the command. For example, if you want to always run ‘dnf’ with sudo you can type:
$ alias dnf=’sudo dnf’
$ dnf upgrade
[sudo] password for jr:
or if you want ‘rm’ to prompt you for confirmation before deleting you can type:
$ alias rm=’rm -i’
$ touch foo
$ rm foo
rm: remove regular empty file ‘foo’?
If you want to know what is being interpreted when you type a command use ‘type’.
$ type dnf
dnf is aliased to
$ type rm
rm is aliased to
rm -i’
You can also print the list of all the current aliases:
$ alias -p
alias cp=’cp -i’
alias rm=’rm -i’
alias mv=’mv -i’
alias ls=’ls –color=auto’
alias ll=’ls -l –color=auto’
(…)
You can remove an alias with the ‘unalias’ command:
$ type dnf
dnf is aliased to `sudo dnf’
$ unalias dnf
$ type dnf
dnf is /usr/bin/dnf
Shell Functions are another fun way to create useful snipplets.
function psman () {
TF=$(mktemp)
man -t “$@” > “$TF” && xdg-open “$TF”
}
You can now type:
$ psman man
and read the man(1) man page in your favourite postscript renderer
Joao Rodrigues
Something happened with the comment formatting.
I think it has something to do with the back-ticks in my copy-paste.
It should be:
(…)
$ type dnf
dnf is aliased to ‘sudo dnf’
$ type rm
rm is aliased to ‘rm -i’
(…)
Thomas
Nice article!
By the export line should not have a dollar sign : “export http_proxy”
Paul W. Frields
@Thomas: Thanks for the catch — fixed!
Xavier Delaruelle
When you need to manage a lot of different shell variables/aliases or if you have to juggle between different shell environments, you may need some tool to dynamically set/unset your environment and keep track of changes you made.
The
shell utility (from the Environment Modules project, https://github.com/cea-hpc/modules/) fills these shell environment handling needs. It relies on modulefiles, which are Tcl scripts describing sets of environment change.
For instance if you have a
modulefile:
set-alias myalias "echo Hello!"
append-path PATH /path/to/myenv/bin
can load and unload this modulefile to dynamically update your current shell session:
bash: myalias: command not found...
$ module load ./myenv
$ myalias
Hello!
$ module unload ./myenv
$ myalias
bash: myalias: command not found...
Read more on http://modules.sourceforge.net/
To give it a try on your Fedora workstation:
Friendly Giraffe
Hi Eduard,
Thanks for the post.
I tried to add my own environment variable a test –
I then tried to check if it existed –
Which returned 0 results.
Where have I gone wrong?
Thanks in advance.
Paul W. Frields
@Giraffe: It’s the errant $ in the command that’s been fixed. On behalf of the author, sorry about that!
Friendly Giraffe
Great thanks a lot Paul, working like a charm now.
Eduard Lucena
Yes, I’m sorry. The export command shouldn’t have the $ sign. It was fixed in the article.
Avi Alkalay
I always put this in ~/.bashrc:
export PS1=’\h:\w\$ ‘;
export HISTCONTROL=ignoredups;
export HISTSIZE=9999999999;
export HISTTIMEFORMAT=’%Y-%m-%dT%H:%M:%S%z :: ‘;
export SEND_256_COLORS_TO_REMOTE=1;
export LC_CTYPE=en_US.UTF-8;
Explanation:
PS1 makes prompt nicer.
Big HISTSIZE will let you record more commands in your history.
HISTTIMEFORMAT will also record the date and time command was issued.
HISTCONTROL=ignoredups will stop wasting your time and disk space with repeating commands.
Avi Alkalay
Instead of aliases, I good practice that I have (especially when you have long history), is to tag long and important commands that I use to type with a small comment at the end. For example, here is a command that I type a lot in my Mac terminal:
$ rsync –iconv=UTF8-MAC,UTF8 -avSH –progress –delete user@home.local:Media/Music/* . #musync
The “#musync” at the end is the tag. Whenever I want to recall this command, I type Ctrl+R and then “musync” and shell history brings it to me ready to be executed.
I call this “fast man’s aliases” ‘cause you don’t need to edit any file to define an alias. It gets recorded right there when you are typing your command.
Jean-Christophe BAPTISTE
Good tip. But much less persistent than aliases (history often gets lost).
Anil
a cool tip that i never saw anywhere 🙂
Paul
awsome!!!!!! Thanks for sharing
amazonguy5465184
When you really start getting into complex syntax ( single quotes, double, backticks ) quoting your alias command may become difficult. Quick solution, throw the command into a function and have your alias call the function name.
instanceslistbyhilappname () {
NAME=$1
printf "%s,%s,%s,%s\n" $(aws --profile saml ec2 describe-instances --output=text --filters "Name=tag:Name,Values=${NAME}" --query 'Reservations[<em>].Instances[</em>].[InstanceType,InstanceId,PrivateIpAddress,Tags[?Key==
].Value]’ | sed s’/ /_/g’)
}
#ALIAS
alias aws-instance-byhilappname=instanceslistbyhilappname
Paul W. Frields
This comment somehow got b0rked by the editor or app. It can be helpful when dealing with blogs, online forums, etc. to pastebin a big snippet like this. Feel free to do that.
rcb
Does the shell read typographic characters?
Such as
U+201C “ Left double quotation mark
and
U+201D ” Right double quotation mark
Should’nt this be ‘quotation marks’?
U+0022 ” 34 Quotation mark
As well as
U+0027 ‘ 39 Apostrophe
which is displayed as
U+2018 ‘ Left single quotation mark
and
U+2019 ’ Right single quotation mark
Entering into the shell
$ text=“fast man’s aliases” && echo $text
(with typographic characters)
returns
Whereas
$ text=”fast man’s aliases” && echo $text
(with quotation marks)
returns
Paul W. Frields
@rcb: As far as I know, it reads only ASCII type characters, not typographic ones.