Time to study: ~75 min
You will learn: the difference between compiled and interpreted languages, how to run a bash script, export, the .bashrc file, aliases, and the PATH variable.
← Chapter 6 | back to Terminal 101 | next: Chapter 8 →
1. brief about compiled and interpreted languages
compiled programs are programs that are translated once into machine code, and then the machine runs that machine code directly, no man in the middle is needed.
c app → c compiler → machine code → machine
which means: 1- faster, 2- more secure, 3- more efficient.
- example languages:
C,Rust,Go.
interpreted programs are executed line by line by an interpreter at runtime. the interpreter reads the code and then translates it to machine code on the fly.
python app → python interpreter → machine code → machine
which means: slower than the compiled ones.
u may get confused, so to make it clearer:
- compiled = translating a whole book at once, then handing over the translated book.
- interpreted = translating sentence by sentence out loud, every time someone wants to read it.
compiled : write → compile → run (compile happens once)
interpreted : write → run (the translating happens every time)
2. the bash script
we just learned the difference between the compiled and the interpreted languages. now we need to know that bash is also an interpreted language.
so we need to know a bit more about how to run compiled and interpreted things in the terminal to get the whole idea.
a compiled language, let’s say C. we first compile the code, then an executable file is created, and then we can run it directly with ./filename:
# 1- compile hello.c and create the executable
gcc hello.c -o hello
# 2- run the executable
./helloHello World
so what happened here is:
hello.c→ gcc compiler →hello(a real new executable file on the disk).
an interpreted language, let’s say python. there is nothing to compile, we hand the file to the interpreter and it runs it:
python3 hello.pyHello World
so what happened here is:
hello.py→ python3 interpreter → the output. notice the difference: no new file is created. withgccwe got ahellofile we could run again by itself, here we get nothing on the disk, only the result.
so what about the bash script?
we have a file called
hello.shand inside it we have:
echo "Hello World"now, how do we run it?
bash hello.shHello World
exactly like python, we call the interpreter and give it the file:
hello.sh→ bash interpreter → the output.
we also have another way to run the bash script, which is the
Shebang. it basically tells the terminal which interpreter to use for this file, by writing the path of it on the very first line with#!/.../...:
#!/bin/bash # the shebang: run this file with /bin/bash
echo "Hello World" # a normal command, exactly as u would type itnow we can run it without writing bash in front of it:
chmod u+x hello.sh
./hello.shHello World
- remember from Chapter 5 that the file needs the execute permission first, otherwise u get
Permission denied. - the shebang must be the first line of the file, if there is even one empty line above it, it stops working.
this is enough to know about bash and interpreted languages.
3. the export command
the
exportcommand is used to send a variable to the environment variables, so u can use it whenever u want by calling$VAR. we already know how to set a variable from Chapter 1:
var="value"
echo $varvalue
but now this variable is a temporary (local) one, so if we want to use it in another script we need to export it to the environment variables:
export VAR="value"
echo $VARvalue
now this
VARvariable is global and can be used in any script that ur shell starts.
- note: the global variable name should be all uppercase,
VARnotvar. it is a convention, not a rule, but everyone follows it so u should too. - note: no space before or after the
=.export VAR = "value"is wrong, the right one isexport VAR="value". - note: this lasts only until u close the terminal. to make it permanent u put it in the
.bashrcfile, which is the next section.
4. the .bashrc configuration file
.bashrcis a configuration file for the bash shell, and it is executed every time a new terminal is opened. for example, i made my own shell show me some random shapes when it opens:
▄▄▄
▄█████▄▄
███▀▀▀▀▀▀▀▀
███▄ ▀ ▀▀
▄ █████▄ █▄
▀▀▄▄ ▄▄▄▀██▀
██▀▀▀██▀ ▀
▀▀▀▀ ▀▀▀▀
▬▬▬▬▬ ▬▬▬▬▬ ▬▬▬▬▬ ▬▬▬▬▬ ▬▬▬▬▬ ▬▬▬▬▬
▬▬▬▬▬ ▬▬▬▬▬ ▬▬▬▬▬ ▬▬▬▬▬ ▬▬▬▬▬ ▬▬▬▬▬
so u can add whatever u want to it, something like this:
# inside ~/.bashrc
echo "hi Mr.$USER"hi Mr.ati
$USERis an environment variable the system sets for u already, u didn’t have to export it.
aliases
an
aliasis a shortcut that refers to a longer command. u write the short name, the shell runs the long thing.
in Chapter 3 we saw the path shortcuts
~,.and..that the shell gives u for free. an alias is how u make ur own shortcuts.
alias hi="echo 'hi Mr.$USER'"
hihi Mr.ati
for example, i created an alias for
cd ..and made it.., so whenever i want to go back i just write..and done. also forcd ../..i made it..., so whenever i write...i go 2 dirs back. and so on, i have a bunch of my own aliases.
alias ..="cd .."
alias ...="cd ../.."# so when i use ... in the terminal :
...
pwd/home/ati
the question is: is it necessary to create all of them? the answer is no, it is just something i prefer, u may not need it. but if u want to have a bunch of ur own aliases then u can do it.
- careful: an alias u type in the terminal disappears when u close it. to keep it forever, write the same line inside ur
.bashrcfile.
this is enough for the
.bashrcfile. if u want to learn more u can dive into it with tutorials, but it is not really needed.
5. the PATH variable
before the
PATHitself, there is a small command that shows u why it exists:which. it tells u where a command actually lives on ur system.
which ls/usr/bin/ls
/usr/bin/lsis the full path of thelscommand. so instead of typing/usr/bin/lsevery time i want to use it, i just typelsdirectly, because the/usr/bindirectory is already stored inside thePATHenvironment variable, which tells the shell where to look for programs.
the
PATHvariable is a list of directories where all the installed programs u have on ur system are. so now to see the list of all of them:
echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/home/ati/.local/bin
- they are separated by
:and the shell searches them in order, from left to right, and stops at the first match.
and this is also the answer to the question from Chapter 5: why do we write
./hello.shand not justhello.sh? because the current dir is not in thePATH, so the shell would never find it. the./is us saying “look right here”.
what if we installed a new program and want to add its path to the
PATHvariable?
# we assign PATH to the old PATH "PATH=$PATH:" and then add the new path after it
export PATH=$PATH:/home/ati/my-programs
echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/home/ati/.local/bin:/home/ati/my-programs
- careful: never forget the
$PATH:part. if u writeexport PATH=/home/ati/my-programsu have just thrown away every other directory, and almost nothing will work in that terminal anymore.
or we can add it to the
.bashrcfile so it is not lost when we close the terminal:
# add the same line inside ~/.bashrc so it survives closing the terminal.
# $PATH: keeps everything that was already there, and we add ours on the end
export PATH=$PATH:/home/ati/my-programs# then in the terminal we run this to load the file again without reopening it
source ~/.bashrcthat’s all, this is enough to know.
NOTES
-
source ~/.bashrcre-reads the file in ur current terminal. u need it every time u change.bashrc, otherwise ur change only shows up in a terminal u open after that. -
everything in this chapter is written for
bash. if u are on another shell the ideas are the same but the config file has a different name, and sometimes the syntax does too. u can check which shell u are on with:
echo $SHELL/usr/bin/fish
bash->~/.bashrczsh->~/.zshrcfish->~/.config/fish/config.fish, andexport VAR="x"becomesset -x VAR x
if that came back as something other than
/bin/bash, read the “before u start” note in the course README before u go further, because it affects every chapter and not only this one.
exportwithout any arguments prints every environment variable u currently have. it is a long list, so it is a good place to uselessfrom Chapter 3.
Assignment
- Make a variable
citywith ur city in it, print it, then open a new terminal and try to print it again. Explain to urself why it is empty. - Now export it, and print it.
- Find out where the
grepcommand lives on ur system. - Print ur
PATHand count how many directories are in it. - Create a script
whoami.shthat printsi am $USER and i live in $city. - Run it the interpreter way, then add a shebang and run it the
./way. - Make an alias
llthat runsls -la, and make it survive closing the terminal.
stuck, or done and want to check? the solutions are here