#!<Path to the executable that will run the script>
#!/bin/bash
#!/usr/bin/python
...# Without a shebang
bash script.sh
# With a shebang
chmod +x script.sh
./script.sh
# "./" is important !$(pwd) # Error: trying to execute the output of the pwd as a command
echo $(pwd) # Good: echo the result of the command as string[ 25 -eq 20 ] # 25 est égal à 20 ?
echo $? # Retourne le résultat de la dernière commande
# 1 --> False
var1=17
var2=18
echo "$( [ $var1 -gt $var2 ]; echo $?)" # 1 --> False
echo "$(test $var1 -ne $var2 ; echo $?)" # 0 --> Truenum1=5
num2=10
sum=$((num1 + num2)) # 15
difference=$((num2 - num1)) # 5
product=$((num1 * num2)) # 50
quotient=$((num2 / num1)) # 2
increment=$((num1++)) # 6sleep 10 &
echo "I don't wait for sleep to finish"
echo "PID of the background process: $!" mkdir mydir && cd mydir
# go to "mydir" only if created successfully [ -f "config.yml" ] || echo "Missing config file"echo "Step 1" ; false ; echo "Step 3"ls | wc -l
# ls list the number of files and send the text result to wc (word count) that count the number of line (-l)
ps aux | grep firefox
# All firefox process# Input <
sort < names.txt
# is equivalent to
cat names.txt | sort
# Output (Overwrite) > 1>
ls > files.txt
ls 1> files.txt
# Create empty file of emty it
> myfile.txt
# Output (Append) >>
echo "new entry" >> log.txt
# Redirect stderr
ls nonexistent 2> errors.txt
# Redirect to stderr and stdout to file
ls /etc /nonexistent > all.txt 2>&1
ls /etc /nonexistent &> all.txt # bash onlycolor=red
[ "$color" = "red" ] && { echo "Color is red"; } \
|| { [ "$color" = "blue" ] && { echo "Color is blue"; } \
|| echo "Color is something else"; }# Option 1: Named function
my_function() {
echo "Hello from function"
}
# Option 2: Function keyword (optional style)
function my_function {
echo "Hello from function"
}
# Call the function
my_functiongreet() {
echo "Hello, $1!"
echo "You passed $# arguments."
}
greet A B
# Hello, A!
# You passed 2 arguments.add() {
echo $(( $1 + $2 ))
}
result=$(add 3 5)
echo "Result is $result"
# Result is 8is_even() {
(( $1 % 2 == 0 )) && return 0 || return 1
}
if is_even 4; then
echo "Even"
else
echo "Odd"
fiVariable are global by default
greet() {
local name=$1
echo "Hi, $name"
}name="World"
echo "Hello, $name!"greeting="Hello, "
name="World"
echo "$greeting$name"
# Hello, World
echo "$greeting Name" # "Hello, Name" <-- double space so not really good
echo "$greetingName" # "" <-- think that this i ona variable name
echo "${greeting}Name" # "Hello, Name" <-- Good !
# "${var}" let us disambiguate the variable namenumber=42
echo "The number is $number"num1=5
num2=10
sum=$((num1 + num2))
echo "The sum is $sum"fruits=("apple" "banana" "cherry")
echo $fruits
# apple
echo ${fruits[@]}
# apple banana cherry
fruits[1]="peach"
# apple peach cherrydeclare -A colors
colors[apple]="red"
colors[banana]="yellow"
colors[grape]="purple"
echo ${colors[apple]}
# red
echo ${colors[@]}
# purple red yellow
# Print function
printarr() { declare -n __p="$1"; for k in "${!__p[@]}"; do printf "%s=%s\n" "$k" "${__p[$k]}" ; done ; }
echo $colors
# grape=purple
# apple=red
# banana=yellow
| Variable | Meaning | Example |
|---|---|---|
$0 |
Name of the script | myscript.sh |
$1 to $9 |
First to ninth argument | $1 = "foo" |
${10} |
Tenth argument and beyond | ${10}, ${11} |
$# |
Number of arguments | 3 if 3 args were passed |
$@ |
All arguments as separate strings | Good for for arg in "$@" |
$* |
All arguments as a single string | One big string of all args |
| Variable | Meaning |
|---|---|
$? |
Exit status of the last command (0 = success) |
$$ |
PID (process ID) of the current script |
$! |
PID of the last backgrounded command (&) |
$- |
Current shell options (e.g., himBH) |
$_ |
Last argument of the previous command |
| Variable | Meaning |
|---|---|
$PWD |
Current working directory |
$OLDPWD |
Previous directory (used with cd -) |
$UID |
Numeric user ID of the current user |
$EUID |
Effective user ID (important for root detection) |
$HOSTNAME |
Name of the machine |
$RANDOM |
Random number (0–32767) |
$SECONDS |
Seconds since shell started |
$LINENO |
Current line number in script |
$BASH_VERSION |
Bash version string |
Format : [ expr1 OP expr2 ] LOG-OP [ expr3 OP expr4 ]
OP :
-eq:==-ne:!=-gt:>-ge:>=-lt:<-le:<=
LOG-OP (Logical Operator):
&&:AND||:OR!:NOT
Test an operator
echo "$([ ... ]; echo $?)"
# 0 --> True
# 1 --> False
# $? output the result of the last commandif CONDITION
then
echo "Error"
fiif CONDITION1
then
echo "Error"
elif CONDITION2 ; then
echo "Perfect"
else
echo "Ok"
fipersonnes="Kyâne Stéphane Quentin"
# for i in {1..10}
# for nom in "Kyâne" "Stéphane" "Quentin"
for nom in $personnes
do
echo "Bonjour $nom"
donewhile CONDITION
do
read -p 'Dites "bonjour" : ' reponse
donePattern matching
file=img.jpg
case "$file" in
*.jpg) echo "It's a JPEG image." ;;
*.sh) echo "It's a shell script." ;;
*) echo "Unknown file type." ;;
esacLogic in condition
day=$(date +%A)
case "$day" in
Monday|Tuesday|Wednesday|Thursday|Friday)
echo "Weekday" ;;
Saturday|Sunday)
echo "Weekend" ;;
esacMultiple commands
read -p "Enter a number (1-3): " num
case "$num" in
1)
echo "You chose One"
echo "First is the best!"
;;
2)
echo "You chose Two"
echo "Second is still great."
;;
3)
echo "You chose Three"
echo "Third time’s the charm."
;;
*)
echo "Invalid choice"
echo "Please enter 1, 2, or 3"
;;
esac [ -z "$var" ] && echo "var is empty"[ -n "$var" ] && echo "var is not empty"[ "$a" = "hello" ] && echo "Match"[ "$a" != "world" ] && echo "Different"[[ "apple" < "banana" ]] && echo "apple is less"[[ "zebra" > "dog" ]] && echo "zebra is greater"[[ $file == *.txt ]] && echo "Text file"[ "$x" -eq 5 ] && echo "Equal"
(( x == 5 )) && echo "Equal"[ "$x" -ne 3 ] && echo "Not Equal"
(( x != 3 )) && echo "Not Equal"[ "$x" -lt 10 ] && echo "Less than 10"
[ "$x" -ge 0 ] && echo "Non-negative"
(( x < 10 )) && echo "Less than 10"
(( x >= 0 )) && echo "Non-negative"[ -e "file.txt" ] && echo "File exists"# Follow symlink
[ -f "file.txt" ] && echo "Regular file"# -L preferred
[ -L "link.txt" ] && echo "It is a symbolic link"
[ -h "link.txt" ] && echo "It is a symbolic link"[ -d "/tmp" ] && echo "Directory exists"
[[ -d "/tmp" ]] && echo "Directory exists"[ -r "file.txt" ] && echo "Readable"
[[ -r "file.txt" ]] && echo "Readable"[ -w "file.txt" ] && echo "Writable"
[[ -w "file.txt" ]] && echo "Writable"[ -x "script.sh" ] && echo "Executable"
[[ -x "script.sh" ]] && echo "Executable"[ -s "log.txt" ] && echo "Has content"[[ $x -gt 0 && $x -lt 10 ]] && echo "Between 1 and 9"
[[ $user == "root" || $user == "admin" ]] && echo "Privileged user"[[ ! -f "missing.txt" ]] && echo "File not found"[ ... ] is limited to only 1 condition, so we use && and || between conditions. Nested conditions not valid.
[ "$a" = "x" ] && [ "$b" = "y" ] && echo "Both match"
[ -f "$file" ] && [ -r "$file" ] && echo "File exists and is readable"
[ -z "$name" ] || [ ! -f "$file" ] && echo "Name empty or file not found"
[ -z "$input" ] || echo "Input is not empty"