Skip to content

Instantly share code, notes, and snippets.

@ArthurDelannoyazerty
Last active July 10, 2025 13:59
Show Gist options
  • Save ArthurDelannoyazerty/5972ba09b57771fd260ad249e3ab5bd7 to your computer and use it in GitHub Desktop.
Save ArthurDelannoyazerty/5972ba09b57771fd260ad249e3ab5bd7 to your computer and use it in GitHub Desktop.

Script execution

Shebang

#!<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 !

Script args $1 $2

echo $1 $2
bash script.sh azerty 1234
# azerty 1234

Command execution $( ... )

$(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 --> True

Arithmetic Evaluation $(( ... ))

num1=5
num2=10
sum=$((num1 + num2))          # 15
difference=$((num2 - num1))   # 5
product=$((num1 * num2))      # 50
quotient=$((num2 / num1))     # 2
increment=$((num1++))       # 6

Command chaining

Background execution &

sleep 10 &
echo "I don't wait for sleep to finish"
echo "PID of the background process: $!" 

AND, execute if success &&

mkdir mydir && cd mydir
# go to "mydir" only if created successfully 

OR, execute if error ||

[ -f "config.yml" ] || echo "Missing config file"

Execute no matter what ;

echo "Step 1" ; false ; echo "Step 3"

Pipe |

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

Redirect output < > >>

# 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 only

AND OR = if else (better with if [ ... ]; then ... fi)

color=red
[ "$color" = "red" ] && { echo "Color is red"; } \
|| { [ "$color" = "blue" ] && { echo "Color is blue"; } \
|| echo "Color is something else"; }

Functions

Simple function

# 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_function

Function arguments

greet() {
  echo "Hello, $1!"
  echo "You passed $# arguments."
}
greet A B
# Hello, A!
# You passed 2 arguments.

Function with return (stdout)

add() {
  echo $(( $1 + $2 ))
}

result=$(add 3 5)
echo "Result is $result"
# Result is 8

Function with return (exit code)

is_even() {
  (( $1 % 2 == 0 )) && return 0 || return 1
}

if is_even 4; then
  echo "Even"
else
  echo "Odd"
fi

Function with local variable

Variable are global by default

greet() {
  local name=$1
  echo "Hi, $name"
}


Variable types

String

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 name

Number

number=42
echo "The number is $number"
num1=5
num2=10
sum=$((num1 + num2))
echo "The sum is $sum"

Array

fruits=("apple" "banana" "cherry")
echo $fruits
# apple
echo ${fruits[@]}
# apple banana cherry
fruits[1]="peach"
# apple peach cherry

Associative Array (dict)

declare -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

Special variables

Positional parameters

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

Exit status, Execution info

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

Other info

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


Logic

Operator

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 command

Logic bloc (If, For, While, Case)

If

if CONDITION
then
  echo "Error"
fi
if CONDITION1
then
  echo "Error"
elif CONDITION2 ; then
  echo "Perfect"
else
  echo "Ok"
fi

For

personnes="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"
done

While

while CONDITION
do
  read -p 'Dites "bonjour" : ' reponse
done

Case

Pattern 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." ;;
esac

Logic in condition

day=$(date +%A)

case "$day" in
  Monday|Tuesday|Wednesday|Thursday|Friday)
    echo "Weekday" ;;
  Saturday|Sunday)
    echo "Weekend" ;;
esac

Multiple 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    

String conditions

Empty string

[ -z "$var" ] && echo "var is empty"

Non empty string

[ -n "$var" ] && echo "var is not empty"

Equal

[ "$a" = "hello" ]  && echo "Match"

Not equal

[ "$a" != "world" ] && echo "Different"

Lexically less

[[ "apple" < "banana" ]] && echo "apple is less"

Lexically greater

[[ "zebra" > "dog" ]] && echo "zebra is greater"

Pattern match

[[ $file == *.txt ]] && echo "Text file"

Equal

[ "$x" -eq 5 ] && echo "Equal"
(( x == 5 ))   && echo "Equal"

Integer Conditions

Not Equal

[ "$x" -ne 3 ] && echo "Not Equal"
(( x != 3 )) && echo "Not Equal"

Less Than, Less Equal, Greater Than, Greater 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"

File Conditions

File exists

[ -e "file.txt" ] && echo "File exists"

Regular file

# Follow symlink
[ -f "file.txt" ] && echo "Regular file"

Sylink

# -L preferred
[ -L "link.txt" ] && echo "It is a symbolic link"
[ -h "link.txt" ] && echo "It is a symbolic link"

Directory

[ -d "/tmp" ]   && echo "Directory exists"
[[ -d "/tmp" ]] && echo "Directory exists"

Readable

[ -r "file.txt" ]   && echo "Readable"
[[ -r "file.txt" ]] && echo "Readable"

Writable

[ -w "file.txt" ]   && echo "Writable"
[[ -w "file.txt" ]] && echo "Writable"

Executable

[ -x "script.sh" ]   && echo "Executable"
[[ -x "script.sh" ]] && echo "Executable"

File not empty

[ -s "log.txt" ] && echo "Has content"

Logical combinations

&& OR, || AND

[[ $x -gt 0 && $x -lt 10 ]] && echo "Between 1 and 9"
[[ $user == "root" || $user == "admin" ]] && echo "Privileged user"

! Negation

[[ ! -f "missing.txt" ]] && echo "File not found"

For [ ... ]

[ ... ] 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"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment