If you want to get a little into bash, this article is for you. We will cover very basic commands in bash, so that after this, you can google everything else
Tested Configuration:
OS: Ubuntu 16.04 LTS
Basics
# declare a variable
# /!\ no SPACE: if you type var = "white rabbit", you'll have an error
var="white rabbit"
# read a variable, access its value (2 ways)
$var
${var}
# print a variable value
echo $var
# length
${#var}
# export through shell
export var
declare -x var
# print every variable defined in the shell
set
# removes a variable
unset var
Array
# store the variable inside the array "arr"
arr[0]=val
# read the first element of "arr"
${arr[0]}
$arr
# every element from "arr"
${arr[*]}
# 11th element from "arr"
${#arr[11]}
# number of element inside "arr"
${#arr[*]}
Cursor Position
# script name
$0
# positon parameters
$1 $2 ... ${10} paramètres positionnels (1, 2 et 10)
# number of positon parameters
$#
# every positon parameters = $1 $2 ... ${n} (2 ways)
$*
$@
# "$1 $2 ... ${n}"
"$*"
# "$1" "$2" ... "${n}"
"$@"
Specials
# reapeat last command
!!
# current shell PID
$$
# last background task PID
$!
# last command
$?
# home path
$HOME
# last dir path
$OLDPWD
# current shell PID
$PATH liste des chemins de recherche des commandes exécutables
# Parent PID = PID of the mother of the shell
$PPID
# Default interaction prompt
$PS1
# Continuation interactive prompt
$PS2
# Prompt used by “select” inside shell script
$PS3
# Used by “set -x” to prefix tracing output -> xtrace DEBUG option
$PS4
# current path
$PWD
# random number
$RANDOM
# seconds this shell has lived
$SECONDS
Conditions
There are two identical ways for testing an expression:
[ XXXX ]
test XXXX
They both return 0 for true, and 1 for false
Well, there is a third way for testing, more bulletproof:
[[ XXXX ]]
recommended version read more about it here
Note: in bash, we don’t use if with =. use eq, lt etc… instead
Note: the spaces inside the brackets are important => this is a wrong way [[XXXXXXX]]
[[ 2 = 2 ]]
echo $?
returns 0
[[ 2 = 3 ]]
echo $?
returns 1
Possible operators:
-
Strings
XXXX = YYYY
XXXX != c2
-z XXXX (true if empty)
-n XXXX (true if not empty) -
Numbers XXXX -eq YYYY (equal)
XXXX -ne YYYY (non equal)
XXXX -lt YYYY (strictly lower than)
XXXX -le YYYY (lower or equal)
XXXX -gt YYYY (strictly greater than)
XXXX -ge YYYY (greater or equal) -
Expressions
! XXXX (true if e is false)
XXXX -a YYYY (true if XXXX and YYYY are true)
XXXX -o YYYY (true if at least XXXX or YYYY is true)
Use conditions with if / else
if [[ condition ]]
then instruction(s)
else instruction(s)
fi
Example
read -p "Si vous etes d'accord entrez o ou oui : " reponse
if [ ! "$reponse" = "o" -a ! "$reponse" = "oui" ]; then
echo "Non, je ne suis pas d'accord !"
else
echo "Oui, je suis d'accord"
fi
Simple oneliner condition &&
if you want to trigger an action only if the previous one succeded, you can do
ls && echo "previous command succeded"
Note: ||
is the opposite, and ;
will trigger both whatever the output of the first command
Create / append to a file
# creates or overwrites a file called read.txt
echo "hello tom" > read.txt
# read this file
cat read.txt
# append a new line to the same file
echo "hello siva" >> read.txt
# read this file again
cat read.txt
Advanced tip:
You can specify what will be outputted with these codes:
1 No error (stdout)
2 error (stderr)
# Nothing will happen (no errors)
echo "hello tom" 2>> error-log.txt
# will create succeded-log.txt and append "hello tom"
echo "hello tom" 1>> succeded-log.txt
# will create error-log.txt and append "-bash: notacommand: command not found"
notacommand 2>> error-log.txt
# will do both
mycommand 1>> succeded-log.txt 2>> error-log.txt
# shortcut when using the same log file
mycommand >> log.txt 2>&1
Check for an existing file
if [[ -f "README.md" ]]
then
echo 'yes the README file exists'
else
echo 'no it does not'
fi
Note: to check the existence of a directory, change the option from f
to d
like so : if [[ -d "myfolder" ]]
Check hardware configuration of your machine
lshw -short
Put a process in the background
This applies to the current shell environment. Let’s say you are editing a file with vi
or nano
. Temporarily, you want to check something in your machine. Then type :
bg
or you can also type Ctrl + z
(Note: some editor can block this shortcut sometimes to avoid confusion)
And you editor will disappear. It’s because it was sent as a background process.
List all the tasks in the background
jobs
Get back your process
fg
# or if you know its number after typing 'jobs' (here the second one)
fg 2
More info here
Tip
&
is a shortcut for running vi
in the forground and ls -la
in the background
vi log.txt & ls -la
Difference between &&
and |
command1 | command2
will take the output of command1
and provide it to command2
While
command1 && command2
will execute command2
only if command1
succeded
echo "test1" && echo "test2"
# outputs
> test1
> test2
echo "test1" | echo "test2"
# outputs
test2
What is /dev/null
it’s the the null device in a UNIX system : whatever you write to /dev/null will be discarded. more info here
Known use : commande >/dev/null 2>&1
to delete every output (stdout & stderr) of command
Template from HackerNews
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
if [[ "${TRACE-0}" == "1" ]]; then
set -o xtrace
fi
if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then
echo 'Usage: ./script.sh arg-one arg-two
This is an awesome bash script to make your life better.
'
exit
fi
cd "$(dirname "$0")"
main() {
echo do awesome stuff
}
main "$@"
Ressources
More about ps1, ps2 … thegeek
More about testing
More about checking if a file exist: linuxize
Difference between bash & sh
lshw manual and tips
bg & fg manual and tips
bg & fg [shorter]((https://til.secretgeek.net/linux/bg_fg_background_and_foreground.html)
very 4 to understand french documentation
explanation & how to use dev/null
from HackerNews 10/2022: best practises