
In this post or cheat sheet, we are going to code some really useful scripts for our daily use.
Last Updated: 03/august/22-
The importance of shebang (#!)
We can see in the first line of a script file, after the shebang, a location. This tell to our system what type of language we are using and where to find it. We can also set our script to run with perl or python, for example. But why there are different starts to specify an interpreter? We can find some script starting with:
- #!/bin/bash
- #!/usr/bin/bash
- #!/usr/local/bin/bash
- #!/usr/bin/env bash
- #!/bin/csh
When we use #!/bin/bash, #!/usr/bin/bash, #!/
usr/local/bin/bash or others, we are defining the absolute path of the language, this could change in different system. We can check where is ours by typing:
$ which bash
/usr/bin/bash
Now when we use:
#!/usr/bin/env bash
“env” could be considered “portable” in that the path to bash is not relevant because it is specified in the environment. In this way, a script author could make his script easier to run on many systems.
This could be a situational parameter because env it will use whatever bash executable appears first in the user’s $PATH. This means that the script could behave differently depending on who runs it. Using another language like python, could be a problem for users with different versions of it.
By specifying #!/usr/bin/python you specify exactly which interpreter will be used to run the script on a particular system.
Another potential problem is that the #!/usr/bin/env trick doesn’t let you pass arguments to the interpreter (other than the name of the script, which is passed implicitly). This usually isn’t an issue, but it can be. When I’m testing a new script, I personally use:
#!/bin/bash -ex
The “e” it would make the script stop if a line in the script fails, and “x” it shows you every line of the script being executed.
How can I execute a script from anywhere?
To make a script able to execute from anywhere, we first need to understand how the scripts are launched. As I say before, the script read what language is defined in the user $PATH to execute the script. So if we add the location of the script to the $PATH, the script can be executed from anywhere. To do this we all need to type:
$ PATH:$PATH:"script path"
$ PATH=$PATH:/home/mati/myScriptFolder
Now if we check the variable $PATH:
$ $PATH
-bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/mati/myScriptFolder
We are going to see our new folder with script at the final of $PATH. Now we can try executing our script simple calling it from anywhere.
Note: This is a temporal solution, if you exit your session, when you enter again you have to do this again.
Add PATH permanently
If you want to add this path permanently, you to need to edit ~/.bashrc file:
$ nano ~/.bashrc
# Go to the bottom, and add the following code, replacing "$HOME/scripts"
export PATH="$PATH:$HOME/scripts"
Type “echo $PATH” to check if everything it’s okay.
Simple scripts
Remember to give execute permission when you create a new script:
$ touch newScript.sh
$ chmod u+x newScript.sh
Full update and upgrade of your system, with “-y” argument you select “Yes” to the size of the download, you have to be careful. Also, you need to run this script as superuser:
#!/bin/bash
# This is for Debian base servers
sudo apt update -y && apt upgrade -y
SSH connection (I recommend to use ssh keys, but if you don’t want to use sshkeys…):
#!/bin/bash
# ssh "user"@"domain or IP" -p "port"
ssh [email protected] -p 2022
Find a file:
#!/bin/bash
echo
echo "Name of the file you need "
read FILE
echo "Write the folder to search "
read FOLDER
FILE="*$FILE*"
set -x
find "$FOLDER" -name "$FILE"
Get information about a folder/files size:
#!/bin/bash
# How much storage is used and in every folder of a path
echo ---------------------------
echo Enter the path to measure
read FOLDER
sudo du -h -x -d1 $FOLDER
Get information about a file:
#!/bin/bash
echo Type file/directory name (using the absolute path)
read FILE
if [ -e "$FILE" ]; then
if [ -f "$FILE" ]; then
echo "$FILE is a regular file."
fi
if [ -d "$FILE" ]; then
echo "$FILE is a directory."
fi
if [ -r "$FILE" ]; then
echo "$FILE is readable."
fi
if [ -w "$FILE" ]; then
echo "$FILE is writable."
fi
if [ -x "$FILE" ]; then
echo "$FILE is executable/searchable."
fi
else
echo "$FILE does not exist"
exit 1
fi
exit
Generate a random password with a predefined length:
#!/bin/bash
echo This is a simple password generator
echo Enter the length of the password:
read PASS_LENGHT
for p in $(seq 1 5);
do
openssl rand -base64 48 | cut -c1-$PASS_LENGTH
done
Encrypt/Decrypt a file/folder:
#!/bin/bash
echo "Simple file encrypter/decrypter"
echo "Choose Encrypt or Decrypt"
choice="Encrypt Decrypt"
select option in $choice; do
if [ $REPLY = 1 ];
then
echo "Please enter the filename you want to encrypt"
read file;
gpg -c $file
echo "The file has been encrypted"
else
echo "Please enter the filename you want to decrypt"
read file2;
gpg -d $file2
echo "The file has been decrypted"
fi
done
Check internet speed (you need to have python installed):
#!/bin/bash
if ! python3 -v <python> &> /dev/null
then
sudo apt install python3 -y
fi
curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python -
I love this one, check the weather using your current location:
#!/bin/bash
program=Weather
version=1.1
year=2022
developer=computer-geek64
case $1 in
-h | --help)
echo "$program $version"
echo "Copyright $year $developer. All rights reserved."
echo
echo "Usage: weather [options]"
echo "Option Long Option Description"
echo "-h --help Show the help screen"
echo "-l [location] --location [location] Specifies the location"
;;
-l | --location)
curl https://wttr.in/$2
;;
*)
curl https://wttr.in
;;
esac

More complex ones
Check status code from a website:
#!/bin/bash -e
## You need to add your sites to list.txt to be checked
## Status code for http: 200= OK. 400= Bad Request. 404= Not found
## You can check all the status codes here:
## https://developer.mozilla.org/es/docs/Web/HTTP/Status
while read line; do
response=$(curl --write-out "%{http_code}\n)" --silent --output /dev/null "$line")
echo $line: $response
done < list.txt
Set up Git:
#!/bin/bash -ex
echo
read -p "Write your git username: " USER
DEFAULT_EMAIL="[email protected]"
read -p "Write your git email [Press enter to accept the private email $DEFAULT_EMAIL]: " EMAIL
EMAIL="${EMAIL:-${DEFAULT_EMAIL}}"
echo "Configuring global user name and email..."
git config --global user.name "$USER"
git config --global user.email "$EMAIL"
echo "Configuring global aliases..."
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.sub "submodule update --remote --merge"
git config --global core.editor "vim"
git config --global credential.helper 'cache --timeout=36000'
read -r -p "Do you want to add ssh credentials for git? [y/n] " RESP
RESP=${RESP,,} # tolower (only works with /bin/bash)
if [[ $RESP =~ ^(yes|y)$ ]]
then
echo "Configuring git ssh access..."
ssh-keygen -t ed25519 -C "$EMAIL"
echo "This is your public key. To activate it in github, got to settings, SHH and GPG keys, New SSH key, and enter the following key:"
cat ~/.ssh/id_ed25519.pub
echo ""
echo "To work with the ssh key, you have to clone all your repos with ssh instead of https. For example, for this repo you will have to use the url: [email protected]:miguelgfierro/scripts.git"
fi
if [ "$(uname)" == "Darwin" ]; then # Mac OS X platform
echo "Setting autocompletion"
AUTOCOMPLETION_URL="https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash"
AUTOCOMPLETION_PATH=/opt/local/etc/bash_completion.d
AUTOCOMPLETION_SCRIPT=git-completion.bash
sudo mkdir -p $AUTOCOMPLETION_PATH
sudo curl -o $AUTOCOMPLETION_PATH/$AUTOCOMPLETION_SCRIPT $AUTOCOMPLETION_URL
source $AUTOCOMPLETION_PATH/$AUTOCOMPLETION_SCRIPT
echo "source $AUTOCOMPLETION_PATH/$AUTOCOMPLETION_SCRIPT" >> ~/.bash_profile
fi
echo ""
echo "git configured"
Create a new user on MySQL:
#!/bin/bash -e
# Create a new user and database on your local mysql server
set -e
usage()
{
cat << EOF
Usage: $0 --user=mysql_user --password=mysql_password
Create a new user and database on your local mysql server
OPTIONS:
-u, --user=user MySQL user
-p, --password=password MySQL password
-r, --root-password MySQL root password
-h, --help Prints this message
EOF
}
verbose=false
#Parse arguments
if [ "$#" -eq 0 ] ; then
usage
exit 2
fi
PARAMS=`getopt -n $0 -o u:p:r:h:v --long user:,password:,root-password:,help,verbose -- "$@"`
eval set -- "$PARAMS"
while true ; do
case "$1" in
-u|--user) mysql_user=$2; shift 2 ;;
-p|--password) mysql_password=$2 ; shift 2 ;;
-r|--root-password) root_password=$2 ; shift 2 ;;
-h|--help) usage ; exit 1 ;;
-v|--verbose) verbose=true ; shift ;;
--) shift ; break ;;
*) usage ; exit 2 ;;
esac
done
# Error checking
error_state=0;
if [ -z "$mysql_user" ] ; then
echo "You MUST specify MySQL user !"
error_state=1
fi
if [ -z "$mysql_password" ] ; then
echo "You MUST specify MySQL password !"
error_state=1
fi
if [ "$error_state" = 1 ] ; then
echo "There are errors in your arguments, exiting."
exit 2
fi
if [ $verbose == true ]; then
echo "Creating user \"$mysql_user\" with associated database"
echo "Password: \"$mysql_password\""
echo "Root password: \"$root_password\""
fi
cd /tmp
cat > create_user.sql << EOF
GRANT USAGE ON *.* TO '$mysql_user'@'localhost';
DROP USER '$mysql_user'@'localhost';
DROP DATABASE IF EXISTS $mysql_user ;
CREATE USER '$mysql_user'@'localhost' IDENTIFIED BY '$mysql_password';
GRANT USAGE ON * . * TO '$mysql_user'@'localhost' IDENTIFIED BY '$mysql_password' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
CREATE DATABASE IF NOT EXISTS $mysql_user character set utf8;
GRANT ALL PRIVILEGES ON $mysql_user . * TO '$mysql_user'@'localhost';
EOF
mysql -uroot -p"$root_password" < create_user.sql
rm create_user.sql
Backup a database:
#!/bin/bash -ex
export PATH=/bin:/usr/bin:/usr/local/bin
TODAY=`date +"%d%b%Y"`
# Update below values
DB_BACKUP_PATH='/backup/dbbackup'
MYSQL_HOST='localhost'
MYSQL_PORT='3306'
MYSQL_USER='root'
MYSQL_PASSWORD='mysecret'
DATABASE_NAME='mydb'
# Number of days to keep local backup copy
BACKUP_RETAIN_DAYS=30
mkdir -p ${DB_BACKUP_PATH}/${TODAY}
echo "Backup started for database - ${DATABASE_NAME}"
mysqldump -h ${MYSQL_HOST} \
-P ${MYSQL_PORT} \
-u ${MYSQL_USER} \
-p${MYSQL_PASSWORD} \
${DATABASE_NAME} | gzip > ${DB_BACKUP_PATH}/${TODAY}/${DATABASE_NAME}-${TODAY}.sql.gz
if [ $? -eq 0 ]; then
echo "Database backup successfully completed"
else
echo "Error found during backup"
exit 1
fi
## Remove backups older than {BACKUP_RETAIN_DAYS} days
DBDELDATE=`date +"%d%b%Y" --date="${BACKUP_RETAIN_DAYS} days ago"`
if [ ! -z ${DB_BACKUP_PATH} ]; then
cd ${DB_BACKUP_PATH}
if [ ! -z ${DBDELDATE} ] && [ -d ${DBDELDATE} ]; then
rm -rf ${DBDELDATE}
fi
fi
Hope you find some useful. I’m going to be updating this post
Pingback: Networking with Linux: commands, services and more – the admin notes
Nice post!