User Tools

Site Tools


bash_scripting

If you want to send us your comments, please do so. Thanks
More on comments


Bash scripting

General remarks

Albeit some commands will work on the command line, they do not work in a script
Example:

sed --quiet '/searchword/!p' /home/user/somefile.txt > /home/user/outfile.txt

Code checking

You can check your code with shellcheck

Beep

Generate a beep: printf '\a'

$-

The value of $- after

  1. a command is exexuted by the user in a terminal on the command line is himBHs
  2. a script is exexuted by the user in a terminal on the command line is hB
  3. a command is exexuted by in a user owned cron job is hB
  4. a script is exexuted by in a user owned cron job is hB

These settings are set via the bash set command or by bash itself

Variables

Variables
You can use variable names consisting of variables by using the eval statement or an array
See How can I use variable variables (indirect variables, pointers, references) or associative arrays?

Subsitution

RSYNC=/usr/bin/rsync
${RSYNC} -a source destination
 
NAME=somename
echo $(echo $NAME         | wc -c)
9
echo $(echo $(echo $NAME) | wc -c)
9
echo $(echo ${NAME}       | wc -c)
9

Count the number of digits

Some solutions

somevariable=hello; echo "${#somevariable}" (5)
somevariable=hello123456; numberofcharacters=$(echo -n $somevariable | wc -c); echo $numberofcharacters (11)
somevariable=hello123456; interimvariable="${somevariable//[^[:alpha:]]/}"; echo "${#interimvariable}" (5)
somevariable=hello123456; awk -F '[0-9]' '{print NF-1}' <<< "$somevariable" (6)
somevariable=hello123456; interimvariable=$(echo "$somevariable" | sed  's/[^0-9]//g'); echo ${#interimvariable} (6)
somevariable=hello123456; echo "$somevariable" | grep -o "[0-9]" | grep -c "" (6)

Complex pipe

When

variablename=$(some piped command)

(command substitution) does not work because of the quotes needed in the pipe command using process subsitution can be a solution

read somevariable < <(some piped command)

Line breaks

Long lines can be broken up by adding a “\” on the place where you want the line to braek and hit ENTER. Mpre than one Space after the “\” is not allowed

New line

A new line (skips one line)

echo -e ""

Two new lines (skips two lines)

echo -e "\n"

Strings and numbers

${1,,}

is a parameter expansion that converts the value of the variable $1 to lowercase

Read data from a file containing variable=value or variable=“value” lines and put them in variables with the same name

source /etc/os-release && DEBIAN="Debian version: $VERSION_ID $VERSION_CODENAME"

Double colons

$ STORAGE=/dev/sda1
$ DISK="${STORAGE::-2}"
$ echo $DISK
$ /dev/sd

Linenumber of string

Get the linenumber a string is on

awk '/somestring/{ print NR; exit }' somefile.txt

Script

#! /bin/bash
if [[ $(date +%_H) -eq 0 ]]; then echo "_H -eq 0"; fi
if [[ $(date +%_H) == 0 ]]; then echo "_H == 0"; fi
if [[ $(date +%H) -eq 0 ]]; then echo "H -eq 0"; fi
if [[ $(date +%H) -eq 00 ]]; then echo "H -eq 00"; fi
if [[ $(date +%H) == 0 ]]; then echo "H == 0"; fi
if [[ $(date +%H) == 00 ]]; then echo "H == 00"; fi
 
if [[ $(date +%_H) -eq 9 ]]; then echo "_H -eq 9"; fi
if [[ $(date +%_H) == 9 ]]; then echo "_H == 9"; fi
if [[ $(date +%H) -eq 9 ]]; then echo "H -eq 9"; fi
if [[ $(date +%H) -eq 09 ]]; then echo "H -eq 09"; fi # Error 09 is not allowed it should be 9 (09 is a string)
if [[ $(date +%H) == 9 ]]; then echo "H == 9"; fi
if [[ $(date +%H) == 09 ]]; then echo "H == 09"; fi

Cronjob

41 0 27,28,29 6 *  /home/user/scripts/tests/stringornumber.sh

Result received in e-mail

_H eq
H eq 0
H eq 00
H == 00

Conclusion

0 is always a number not a string
00 can be a number or a string
09 is always a string

Number output

This will round to three digits. The comma might be a dot according to your LC_NUMERIC locale setting

printf %g 453,1427934923
453,143

This will also print the thousand separators

printf "%'d" 4531427934923
4.531.427.934.923

Conditional statements

if

Functions

Test a function in a (library) file

. $HOME/lib/libthing.sh; FUNCTIONNAME

Debugging

Try to comment out a line with a #. If the line does not change in a comment line the problem is upstream in the code. This will help finding missing quotes
Turn on debugging mode with

set -x

Code checking tools

shellcheckOur favorite
shove
shunit2

shellcheck

Error SC1090

SC1090
Code:

. /home/user/externalfile.sh
^-- SC1090: Can't follow non-constant source. Use a directive to specify location.

Solutions:

  • Add “# shellcheck source=/home/user/externalfile.sh” before the line with the code (did not work for us)
  • “Use the -x option to check the external file as well (did not work for us)
  • Leave the message be

Error SC1091

SC1091
Code:

. /home/user/externalfile.sh
^-- SC1091: Not following: /home/user/externalfile.sh was not specified as input (see shellcheck -x)."

This is strange. We expected SC1090. SC1091 is for an other issue. SC1090 occurred on the line after the line which caused SC1091
Solutions:

  • Use the -x option to check the external file as well (did not work for us)
  • Leave the message be

Error SC2028

Code:

echo "Some text.\\nSome more text"
                 ^-- SC2028: echo won't expand escape sequences. Consider printf.

Solution: The -e option has to be added to the echo command

echo -e "Some text.\\nSome more text"

Tools

ProgramExampleRemark
pgrep Does ps -aux | grep . Part of procps or procps-ng or an other, at this moment unkown to us, package. Check if it is installed before installing an other package
pkill Send the specified signal (by default SIGTERM) to each found process. Part of procps or procps-ng or an other, at this moment unkown to us, package. Check if it is installed before installing an other package
psps h -p 12084 -o %cpu,%memShows the cpu and memory load of process 12084 without headers. %cpu: CPU time used divided by the time the process has been running. Ratio of the process's resident set size to the physical memory on the machine. Both are expressed as a percentage
sleepsleep 0.01Delay for a certain time. Also times less than one second

Cases

Anacron
Array
Braces
Calculations
case
cron
Check if X windows is running
Command exit codes
Color
Command line arguments
Cursor movement
Editing text
for
Functions
if
Notifier
Shell Function Definitions - see man bash (search for it)
search end replace
reading a line
true and false
Use of spaces
while
zenity

TEST=Hello; echo “${#TEST}“
Output: The number of characters held in TEST. In this case: 5

xfce general monitor solutions

System load

  • Make a script /home/user/load.sh
  • Make it executable for the user with chmod 740
  • Put
    #! /bin/bash
    uptime | cut -d "a" -f 4 | tr , " " | tr -s " " | cut -d " " -f 2-4 | tr " " "\n"

    in it

  • Make a new Generic Monitor in the panel
  • Put /home/user/load.sh in the Command field
  • Adjust the font size to you needs
  • Set the Period to 2 seconds

Run PHP code

php -r 'echo "Hello World\n";'

Remarks

(wd: /somepath)
(wd now: ~)

wd stands for working directory

Errors

If you get one of

test.sh: 3: [: ==: unexpected operator
test.sh: 3: test.sh: [[: not found

then

#! /bin/bash

is probably missing in the first line of test.sh, your script

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
bash_scripting.txt · Last modified: 16-12-2023 15:09 by wim