Linux:Scripts: Difference between revisions

From Cheatsheet
Jump to navigationJump to search
Tag: Manual revert
 
(37 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Category:Cheatsheet]]
[[Category:Cheatsheet]]


== Common ==
== Advice ==
* Lowercase or Camelcase only: all BASH variables are uppercase, so don't get in their way!


== Templates ==
=== #1 ===
Script with a single passed variable, description and common exit-protocols.
<syntaxhighlight lang='bash'>
#!/usr/bin/env bash
set -o errexit      # Exit on error, do not continue running the script
set -o nounset      # Trying to access a variable that has not been set generates an error
set -o pipefail      # When a pipe fails generate an error
if [[ "${1-}" =~ ^-*h(elp)?$ ]] || [[ "$#" -eq 0 ]] ; then
    echo ""
    echo 'Usage: myscript.sh value1
This is the description of my script.
'
    exit
    echo ""
fi
</syntaxhighlight>
=== #2 ===
Inspired by: https://stackoverflow.com/questions/16483119/an-example-of-how-to-use-getopts-in-bash
Dedicated usage/help function to catch faulty script usage. This template catches custom flags and save them as variables.
<syntaxhighlight lang='bash'>
#!/usr/bin/env bash
set -o errexit      # Exit on error, do not continue running the script
# We comment this because we explicitly check for variable existence later
#set -o nounset      # Trying to access a variable that has not been set generates an error
set -o pipefail      # When a pipe fails generate an error
# Basic help output
usage () {
    echo ""
    echo "Usage: ${0} -s something -o something-else
Examples:
${0} -s herp -o derp
This is the description of my script.
"
    exit 0
    echo ""
}
# Catch insufficent arguments and or help parameter, then run the usage function
if [[ "${1-}" =~ ^-*h(elp)?$ ]] || [[ "$#" -lt 2 ]] ; then
    usage
fi
# Create options "s" and "o" and save them as variables "var1" and "var2" respectively
# Missing or wrong arguments will run the usage function
while getopts ":s:o:" arg; do
    case "${arg}" in
        s) var1=${OPTARG};;
        o) var2=${OPTARG};;
        *) usage ;;
    esac
done
# Remove parsed parameters done by getopts, so that any remaining options can be interpreted as i.e. $1, $2, $3 etc
shift $((OPTIND-1))
# Check whether the filled arguments are not empty, set -o nounset was commented to make this work properly
# If the variables aren't filled, run the usage function
if [[ -z "${var1}" ]] || [[ -z "${var2}" ]]; then
    usage
fi
</syntaxhighlight>
== Common syntax ==
=== for ===
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
# Execute a command within all objects in a folder.
# Execute a command for all objects within this folder and all subdirectories
for i in *; do du -h "$i" ; done
for i in *; do du -h "$i" ; done
# Execute a command x amount of times based on $i
for((i=1;i<=5;++i)); do dd if=/dev/zero of=myshare/file-$i bs=1M count=1; done
# Shell script version - Execute a command x amount of times based on $i
for((i=1;i<=5;++i)) do
echo $i
done
</syntaxhighlight>
</syntaxhighlight>


=== if ===
==== Testing - [[ ]] ====
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
# man test
# Use the test functionality [[ ]] to compare values and types using expressions
[]
man test
Brackets are for checking whether something is true or not.
 
if [ -d "$D" ]
# Test whether the directory saved in the $MyDirectoryVariable variable exists
then
[[ -d "$MyDirectoryVariable" ]]


# Combine testing with an if statement
if [[ $(echo "world") == "world" ]]; then
    echo -e "all is bad in da world"
else
else
    echo -e "all is good"
fi
</syntaxhighlight>
</syntaxhighlight>
=== if ===
 
<pre>
<pre>
[ -d "$FILE" ] = If file exists
https://stackoverflow.com/questions/638975/how-do-i-tell-if-a-file-does-not-exist-in-bash
[ -f "$FILE" ]  = If directory exists
 
FILE=/home/javier/wopper.txt
[ -b "$FILE" ] = Block special file
[ -c "$FILE" ] = Special character file
[ -d "$FILE" ] = If directory exists
[ -e "$FILE" ] = Check for file existence, regardless of type (node, directory, socket, etc.)
[ -f "$FILE" ] = Check for regular file existence not a directory
[ -G "$FILE" ] = Check if file exists and is owned by effective group ID
[ -G "$FILE" ] = set-group-id - True if file exists and is set-group-id
[ -k "$FILE" ] = Sticky bit
[ -L "$FILE" ] = Symbolic link
[ -O "$FILE" ] = True if file exists and is owned by the effective user id
[ -r "$FILE" ] = Check if file is a readable
[ -S "$FILE" ] = Check if file is socket
[ -s "$FILE" ] = Check if file is nonzero size
[ -u "$FILE" ] = Check if file set-user-id bit is set
[ -w "$FILE" ] = Check if file is writable
[ -x "$FILE" ] = Check if file is executable
 
FOLDER=/home/javier/
[ -d "$FOLDER" ]  = If directory exists
</pre>
</pre>


==== Examples ====
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
FILE=~/todo.txt
FILE=~/todo.txt
Line 28: Line 139:
  cat "~/todo.txt"
  cat "~/todo.txt"
else
else
  echo "“Je hebt nog geen todo.txt! Maak deze z.s.m. aan."
  echo "You don't have the file, so you should make it."
fi
</syntaxhighlight>
 
<syntaxhighlight lang='bash'>
USER=$(whoami)
FILE=~/todo.txt
 
if [ "$USER" != "root" -a -f "$FILE" ]; then
echo "You're a normal user, you do have the file and this is its output:"
cat "$FILE"
elif [ "$USER" != "root" -a ! -f "$FILE" ]; then
echo "You're a normal user, you don't have the file, so you should make it."
fi
fi
</syntaxhighlight>
</syntaxhighlight>


== SSH ==
== Scripts ==
=== centos-create-user.sh ===
=== SSH ===
==== centos-create-user.sh ====
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
#!/bin/bash
#!/bin/bash
Line 61: Line 185:
</syntaxhighlight>
</syntaxhighlight>


=== ubuntu-create-user.sh ===
==== ubuntu-create-user.sh ====
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
#!/bin/bash
#!/bin/bash
Line 92: Line 216:
</syntaxhighlight>
</syntaxhighlight>


== Mail ==
=== Mail ===
=== Automatic sendmail ===
==== Automatic sendmail ====
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
#!/bin/bash
#!/bin/bash

Latest revision as of 16:29, 24 January 2026


Advice

  • Lowercase or Camelcase only: all BASH variables are uppercase, so don't get in their way!

Templates

#1

Script with a single passed variable, description and common exit-protocols.

#!/usr/bin/env bash

set -o errexit       # Exit on error, do not continue running the script
set -o nounset       # Trying to access a variable that has not been set generates an error
set -o pipefail      # When a pipe fails generate an error

if [[ "${1-}" =~ ^-*h(elp)?$ ]] || [[ "$#" -eq 0 ]] ; then
    echo ""
    echo 'Usage: myscript.sh value1

This is the description of my script.
'
    exit
    echo ""
fi

#2

Inspired by: https://stackoverflow.com/questions/16483119/an-example-of-how-to-use-getopts-in-bash

Dedicated usage/help function to catch faulty script usage. This template catches custom flags and save them as variables.

#!/usr/bin/env bash

set -o errexit       # Exit on error, do not continue running the script
# We comment this because we explicitly check for variable existence later
#set -o nounset       # Trying to access a variable that has not been set generates an error
set -o pipefail      # When a pipe fails generate an error

# Basic help output
usage () {
    echo ""
    echo "Usage: ${0} -s something -o something-else
Examples:
${0} -s herp -o derp

This is the description of my script.
"
    exit 0
    echo ""
}

# Catch insufficent arguments and or help parameter, then run the usage function
if [[ "${1-}" =~ ^-*h(elp)?$ ]] || [[ "$#" -lt 2 ]] ; then
    usage
fi

# Create options "s" and "o" and save them as variables "var1" and "var2" respectively
# Missing or wrong arguments will run the usage function
while getopts ":s:o:" arg; do
    case "${arg}" in
        s) var1=${OPTARG};;
        o) var2=${OPTARG};;
        *) usage ;;
    esac
done

# Remove parsed parameters done by getopts, so that any remaining options can be interpreted as i.e. $1, $2, $3 etc
shift $((OPTIND-1))

# Check whether the filled arguments are not empty, set -o nounset was commented to make this work properly
# If the variables aren't filled, run the usage function
if [[ -z "${var1}" ]] || [[ -z "${var2}" ]]; then
    usage
fi

Common syntax

for

# Execute a command for all objects within this folder and all subdirectories
for i in *; do du -h "$i" ; done

# Execute a command x amount of times based on $i
for((i=1;i<=5;++i)); do dd if=/dev/zero of=myshare/file-$i bs=1M count=1; done

# Shell script version - Execute a command x amount of times based on $i
for((i=1;i<=5;++i)) do
echo $i
done

if

Testing - [[ ]]

# Use the test functionality [[ ]] to compare values and types using expressions
man test

# Test whether the directory saved in the $MyDirectoryVariable variable exists
[[ -d "$MyDirectoryVariable" ]]

# Combine testing with an if statement
if [[ $(echo "world") == "world" ]]; then
    echo -e "all is bad in da world"
else
    echo -e "all is good"
fi
https://stackoverflow.com/questions/638975/how-do-i-tell-if-a-file-does-not-exist-in-bash

FILE=/home/javier/wopper.txt
[ -b "$FILE" ] = Block special file
[ -c "$FILE" ] = Special character file
[ -d "$FILE" ] = If directory exists
[ -e "$FILE" ] = Check for file existence, regardless of type (node, directory, socket, etc.)
[ -f "$FILE" ] = Check for regular file existence not a directory
[ -G "$FILE" ] = Check if file exists and is owned by effective group ID
[ -G "$FILE" ] = set-group-id - True if file exists and is set-group-id
[ -k "$FILE" ] = Sticky bit
[ -L "$FILE" ] = Symbolic link
[ -O "$FILE" ] = True if file exists and is owned by the effective user id
[ -r "$FILE" ] = Check if file is a readable
[ -S "$FILE" ] = Check if file is socket
[ -s "$FILE" ] = Check if file is nonzero size
[ -u "$FILE" ] = Check if file set-user-id bit is set
[ -w "$FILE" ] = Check if file is writable
[ -x "$FILE" ] = Check if file is executable

FOLDER=/home/javier/
[ -d "$FOLDER" ]  = If directory exists

Examples

FILE=~/todo.txt
if [ -f "$FILE" ]; then
 cat "~/todo.txt"
else
 echo "You don't have the file, so you should make it."
fi
USER=$(whoami)
FILE=~/todo.txt

if [ "$USER" != "root" -a -f "$FILE" ]; then
 echo "You're a normal user, you do have the file and this is its output:"
 cat "$FILE"
elif [ "$USER" != "root" -a ! -f "$FILE" ]; then
 echo "You're a normal user, you don't have the file, so you should make it."
fi

Scripts

SSH

centos-create-user.sh

#!/bin/bash
# Execute as root
# Usage: ./centos-create-user.sh USER

USER="$1"

echo "Creating user ${USER}"
useradd -m ${USER} -G wheel

echo "Creating authorized keys file and settings rights for ${USER} user"
mkdir -p /home/${USER}/.ssh

cat << 'EOF' >> /home/${USER}/.ssh/authorized_keys
# PUT ANY KEYS IN HERE
# KEY-1
# KEY-2
# KEY-3
EOF

chown -R ${USER}:${USER} /home/${USER}/.ssh
chmod 700 /home/${USER}/.ssh
chmod 600 /home/${USER}/.ssh/authorized_keys

# EOF

ubuntu-create-user.sh

#!/bin/bash
# Execute as root
# Usage: ./ubuntu-create-user.sh USER

USER="$1"

echo "Creating user ${USER}"
adduser ${USER} --disabled-password

echo "Adding ${USER} to the sudo group"
usermod -aG sudo ${USER}

echo "Creating authorized keys file and settings rights for ${USER} user"
mkdir -p /home/${USER}/.ssh

cat << 'EOF' >> /home/${USER}/.ssh/authorized_keys
# PUT ANY KEYS IN HERE
# KEY-1
# KEY-2
# KEY-3
EOF

chown -R ${USER}:${USER} /home/${USER}/.ssh
chmod 700 /home/${USER}/.ssh
chmod 600 /home/${USER}/.ssh/authorized_keys

# EOF

Mail

Automatic sendmail

#!/bin/bash
#requires: date,sendmail
function fappend {
    echo "$2">>$1;
}
YYYYMMDD=`date +%Y%m%d`

# CHANGE THESE
TOEMAIL="ADMINISTRATOR@MYDOMAIN.COM";
FREMAIL="FROMNOREPLY@MYDOMAIN.com";
SUBJECT="E-mail Subject";
MSGBODY=$(Command);

# DON'T CHANGE ANYTHING BELOW
TMP=`mktemp`

rm -rf $TMP;
fappend $TMP "From: $FREMAIL";
fappend $TMP "To: $TOEMAIL";
fappend $TMP "Reply-To: $FREMAIL";
fappend $TMP "Subject: $SUBJECT";
fappend $TMP "";
fappend $TMP "$MSGBODY";
fappend $TMP "";
fappend $TMP "";
cat $TMP|/usr/sbin/sendmail -t;
rm $TMP;