Terminal aka shell, CLI are all same, its an application that accepts text based inputs and gives result on the screen.
In earlier days, terminal is just a physical device(something like joystick) that we can type commands in that using keyboard. Nowadays if we talk about terminal that means its terminal-emulator(default or kitty or iterm or ghostty etc), this terminal-emulator will take the inputs in the form of text and a shell(zsh, bash, fish etc) is responsible for executing this and the terminal-emulator just displays that in window.
If our modern terminal(terminal-emulator) is just a text-inputer and output application, then which is responsible for executing.
Shell is the one is responsible for executing those, it is often called as REPL
R => Read
E => Eval(execute the output, similar to eval in js)
P => Print
L => Loop
Different Operating system uses different shells, for eg: linux uses bash, mac uses zsh,
only god knows what windows is doing.
Both bash and zsh are pretty much same, since mac and linux follows UNIX. fish uses
its own specific syntax compared with bash and zsh.
Shells is like a programming language, it has everything when compared with normal programming
languages like loops, conditional statements, functions etc.
for Eg:
name="Manikandan" // variable declaration
echo $name // prints Manikandan
Every data, basically every stuff is stored either as files or directories in our computer, files and directories are organized in a tree like structure(in linux) Don't ask me about windows
Directories are just folders, which can contains other directories inside that(this can go to any nested level) or files.
Files are the stuff, which contains raw binary data 0 or 1, for user preferences these binary data often
displayed in some readable formats like .txt(text based files), .png.jpg.jpeg(images), .mp4(videos)
end of the day all these represent raw binary data 0 or 1 at low level
Filesystem often starts with root directory, from here it will directories like bin etc, usr, home etc
Above is a sample linux directory/file structure, this is just a high level structure
Consider the below folder structure
Consider if you are currently in user directory/folder, if you want to navigate to file1 you could use dir1/dir2/file1 => this is called relative path.
Consider the same if you are currently in user directory/folder, if you want to navigate to file1 you could use /user/dir1/dir2/file1 => this is called absolute path.
Consider if you are currently in file1 file, if you want to navigate to parent dir1 you could use ../../dir1 => this is called relative path.
Consider the same if you are currently in file1 file, if you want to navigate to parent dir1 you could use /user/dir1 => this is called absolute path.
cat FILE_NAME1....N - This command is use to view the contents of any file in terminal, originally this is used to concatinate multiple files and view
head -n INTEGER FILE_NAME1...N - This command used to print the number of lines specified in the command after -n from the top of the file. for eg: if a file has 100 lines and if we use head -n 10 file this will print first 10 lines.
tail -n INTEGER FILE_NAME1...N - This command is exactly similar to head, but vice versa
less FILE_NAME - This command will basically displays the file in an interactive form, where you can use your vim motions to interact with the file.
touch FILE_NAME1....N - This command will basically creates a new file with given name, it also use to create multiple filenames in one command. if the file name exists, it updates the timestamp of the file details.
mkdir DIR_NAME1....N - This command will be used to create a new directory with given name, it also use to create multiple directories in one command. if the directory already exists it throws an error.
mv SRC_PATH DEST_PATH - This command will be used to move a file or directory to another directory, you can also use this command to rename a file like mv resume.txt resume_updated.txt
rm -r FILE OR DIR - This command will be used to remove a file or directory, -r is used to recursively remove all files/folders inside a directory.
cp SRC_PATH DEST_PATH - This command will be used to copy a file or directory to another location , you can -R is specified to copy the inside level files or directories when copying any directory.
grep - This command alone needs a separate notes section, so i will keep it simple here this command is use to search any word in file, it can case sensitive, insensitive, regex etc, grep can also be used to search a word in multiple files.
find DIR_PATH -name FILE_NAME - This command is use to find the location of the file from anywhere in your directory.
In unix kinda systems(mac, linux), there are multiple users that we can have, each user will have their own directory from the root, for eg: /user1/**, /user2/**. whenever any user loggedin, the terminal will have their own directory at the start.
sudo - superuser do This command use to execute certain commands with certain privileges.
permission is often represented by 10-character string(drwxrwxrwx), to determine
which files/directories can be accessed by who.
Permission basically decides two stuffs, who has the permission? what permission does this user
has?
who has the permission? => basically states which users has permission for any files or folders.
what permission does this user has? => this states what level of permission does any user has,
for eg: whether he has read only, or both read and write etc
Lets breakdown this drwxrwxrwx
drwxrwxrwx => the first letter d states that it is a directory.
-rwxrwxrwx => the first letter - states that it is a file.
rwxrwxrwxthe rest of 9 characters is split into 3 sets with rwx
rwx - r represents read permission is there.
-wx - - represents read permission is not there, but write and executable permission is there.
rwx - w represents write permission is there.
r-x - - represents write permission is not there, but read and executable permission is there.
rwx - x represents executable permission is there.
rw- - - represents executable permission is not there, but read and write permission is there.
adding to the above any combination is also possible here for eg: --x,r--,-w-
Ok, now coming to why there are 3 sets then rwxrwxrwx
1st set of rwx represents permission set for owner of the file or directory, mostly
the owner means the one who creates that file or directory, this can also be manually changed.
2nd set of rwx represents permission set for a group of users, in unix like systems
there are groups, which is what you think, basically a group of users, for eg: developers, support engineers etc
3rd set of rwx represents permission set for others(basically everyone).
chmod - change mode - This command is used to change the permission of any file or directory.
sudo - sudo is basically is used to execute anything with root user, for eg: lets say file1.txt
is having permission of -rw-------, you can see this file is not having executable permission
but if it is executed as sudo, this will start executing.
chown - used to change the ownership of the file.
Programs or executables are more or less the same, the bash, zsh, fish etc scripts that we are writing
is also called as programs or executables.
Usually there are two kinds of programs, compiled and Interpretted
Compiled programs are converted into machine code and we can directly execute the machine code,
our OS will execute this without any tool/help.
Interpretted programs are the one where another program called interpretter needs to be there
to execute this, for eg: javascript needs an interpretor to run it, python the same, in this category
shell also exists.
/bin/sh is the program that is responsible for executing our shell scripts(basically programs
with setup.sh, program.sh etc)
shebang as i said before shell scripts needs an interpretor to run(sh, bash, fish etc),
shebang will basically tells the program that we write(setup.sh) which interpretor needs to execute
this program, it is usually specifies on top(first line) of the code(#!interpretor).
eg: #!usr/bin/env bash.
Both zsh and bash has configuration kinda files, where .zshrc and .bashrc are the filenames that
it gets the configuration and these are located at home directory.
This is one of the important stuff that needs to be explained.
PATH is one of the built-in environment variable that every unix based system has.
all the commands that we are running cd, ls, sh, mkdir, touch etc, the shell needs to understand
these executables right, coz its not in any particular folder that you are executing, in order to
give shell that these executables are present in some folder, we will specify that folder in path separated
by :, the shell will then look into all those folders.
man - manual as the abbreviation suggest man is manual for other commands or programs. it contains documentation for all the built in unix commands and stuff. for eg: man ls, man cd.
--help or -h or help this command is used to get any help of any command. its not a replace for man, man is kinda entire manual for the command, --help is more of a short help, that can have some specific help commands.
exit codes - 0 is the exit code for success and rest of the numbers represents error.
stdout - standard output - this is basically how our shell outputs the data in our terminal using streams, cd, echo, ls, grep etc whichever commands that are outputing data into terminal is basically the standard output.
stderr - standard error - this is standard error, this is also a data stream that outputs into our terminal as error messages.
Redirecting streams > 2> - the two operators >, 2> is used to redirect your output
stream and error stream into a file.
for EG: echo "Manikandan" > test.txt; (after this command executed Manikandan will be saved into test.txt)
cd dummy_text 2> error.txt; (since this is a dummy_text, cd will throw error, that will be redirected and saved into
error.txt)
stdin - standard in its a standard input, in terminal REPL the loop is always receives an input from user.
| - pipe
pipe is one of the most powerful character, it basically takes an output of one program/command
and make it as the input to another program/command.
for EG: echo "Manikandan" | wc -w -> here first command echo produces a standard output, that will be
passed as an input to the wc(word count) command.
ctrl + c - interrupt - this command is used to interrupt a command, if you run a command,
in the middle if you think this won't work, if left as it is, this would run forever, but if you
press ctrl + c the terminal will send a SIGINT and stop it.
There are some cases where you might not be able to stop/interrupt the program, in those scenarios
you can use kill command with pid(processID)(which you can grab from ps command).
Packages are nothing but third party packages/commands that can be used in our system(similar to npm, pip etc)
In ubuntu(linux) the default package manager is apt, for EG: if you want to install neovim you can do something like sudo apt install neovim.
In mac there is no default package manager, but unofficially homebrew(brew) is kinda official pacakage manager, for EG: if you want to install neovim you can do something like brew install neovim.
NOTE: sudo is required since we are installing a new system level command/package.Terminals are just a input/output getter and shower.
Once the input has been get by terminal a shell will execute that and returns the output to terminal and it will show.
shells are different types default one is sh, bash is the superset(with more features) to sh, zsh is similar to bash for macos, fish with easier syntax then bash and zsh.
The shells are the interpretors for all the shell program that we write. eg: setup.sh, scripts.sh etc basically when we try to execute ./setup.sh or ./scripts.sh, defaultly configured shell will execute this script it can be bash, zsh or sh or fish or anything.
shebang is an operator, which specifies which interpretor needs to be used for a particular program. basically when we try to execute ./setup.sh or ./scripts.sh with shebang, whatever we specified in shebang will be executed with that interpretor.
.sh files are recognized by both zsh and bash
without shebang also any file can be executed with the shell that we want, for eg; without shebang program setup.sh can be executed by fish setup.sh(fish interpretor is used), bash setup.sh(bash interpretor is used)
Without shebang
Executing without shebang program with different interpretors
With shebang
if am executing with shebang, the interpretor what we configured in the program will be taken precedence