User Tools

Site Tools


program_lang:bash

BASH

IF

if or compare text

if [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]
if [ $a == $b -o $b == $c -o $a == $c ]

if and

if [ $a == $b -a $b == $c -a $a == $c ]
if [ "$fname" = "a.txt" ] && [ "$fname" = "c.txt" ]

Use CSV file

Change column order

Switch column 1 and 3 serared by ;

[root@lnx01 ~]# echo "1;2;3;4;5"  |  awk -F';' '{ t = $3 ; $3 = $1; $1 = t; print; }' OFS=';'
3;2;1;4;5

backup files and folders permissions

Here an easy way to convert rwx in octal

[root@lnx01 ~]# find ./  -printf '%m:%u:%g:%p\0\n'
750:root:root:./libiconv-1.14-3.aix5.1.ppc.rpm
750:root:root:./libraqm-0.7.0-4.el7.src.rpm
755:root:root:./libssl.so.1.0.2
700:root:root:./rpmbuild
700:root:root:./rpmbuild/SOURCES
664:root:root:./rpmbuild/SOURCES/raqm-0.7.0.tar.gz
700:root:root:./rpmbuild/SPECS
644:root:root:./rpmbuild/SPECS/libraqm.spec
750:root:root:./libraqm-0.7.0-4.el7.x86_64.rpm
750:root:root:./libwebp7-1.0.3-1.el7.remi.x86_64.rpm
750:root:root:./php-mbstring-7.4.24-1.fc33.remi.x86_64.rpm
700:root:root:./php56-php-mbstring-5.6.40-28.el7.remi.x86_64.rpm

Here another more advanced output, with UID, GID…

[root@lnx01 ~]# find ./  -printf '%Y:%m:%U:%G:%a:%p\0\n'
f:750:0:0:Fri Oct 15 02:29:02.0764754025 2021:./libraqm-0.7.0-4.el7.src.rpm
f:755:0:0:Fri Oct 15 02:29:02.0789754200 2021:./libssl.so.1.0.2
d:700:0:0:Sun Oct 17 10:34:56.0564143056 2021:./rpmbuild
d:700:0:0:Sun Oct 17 23:08:59.0437891139 2021:./rpmbuild/SOURCES
f:664:0:0:Fri Oct 15 02:29:02.0837754536 2021:./rpmbuild/SOURCES/raqm-0.7.0.tar.gz
d:700:0:0:Sun Oct 17 23:08:59.0437891139 2021:./rpmbuild/SPECS
f:644:0:0:Fri Oct 15 02:29:02.0863754718 2021:./rpmbuild/SPECS/libraqm.spec
f:750:0:0:Fri Oct 15 02:29:02.0863754718 2021:./libraqm-0.7.0-4.el7.x86_64.rpm
f:750:0:0:Fri Oct 15 02:29:02.0863754718 2021:./libwebp7-1.0.3-1.el7.remi.x86_64.rpm
f:750:0:0:Fri Oct 15 02:29:02.0873754788 2021:./php-mbstring-7.4.24-1.fc33.remi.x86_64.rpm
f:700:0:0:Fri Oct 15 02:29:02.0893754927 2021:./php56-php-mbstring-5.6.40-28.el7.remi.x86_64.rpm

compare decimal

Error message when comparing 2 number, when decimal are user

integer expression expected

You can use bc Ex:

size=10.5
max_sz=10

if [[ $(bc <<<"${size} > ${max_sz}") == "1" ]]
then
  echo "${size} is bigger than ${max_sz}" 
fi

basename

Error when using basename command

[storage@lnx01l scripts]$ basename $0
basename: invalid option -- 'b'
Try 'basename --help' for more information.
[storage@lnx01l scripts]$ basename -- $0
-bash

You can also use the first occurence when using su

instead su - myuser -c "myprog.sh"
use su - myuser "myprog.sh"

Explanation: When you execute the script in the context of the running shell (which is started via the “-c” option of su), that makes it an interactive shell (hence the -bash is the value of $0). So the “basename -bash” fails as “-b” is not a valid option…

array

Define an array

allThreads=(1 2 4 8 16 32 64 128)

List all Items from array

${allThreads[@]}

List the first item

${logPaths[0]}

arr=() 	Create an empty array
arr=(1 2 3) 	Initialize array
${arr[2]} 	Retrieve third element
${arr[@]} 	Retrieve all elements
${!arr[@]} 	Retrieve array indices
${#arr[@]} 	Calculate array size
arr[0]=3 	Overwrite 1st element
arr+=(4) 	Append value(s)
str=$(ls) 	Save ls output as a string
arr=( $(ls) ) 	Save ls output as an array of files
${arr[@]:s:n} 	Retrieve n elements starting at index s

Exemple

#!/usr/bin/bash
declare -a Users=('user01' '1001' '1000' '' '' '/bin/bash')
Users+=('user02' '1002' '1003' '' '' '/bin/bash')
Users+=('user03' '1003' '4' 'Recovery user' '' '/bin/bash')

UserNbProps=6
let NbUsers=${#Users[@]}/$UserNbProps

for (( i=0; i<$NbUsers; i++ ))
do
  let ArrayIndex=i*UserNbProps
  Line=$(cat /etc/passwd | grep "^${Users[$ArrayIndex]}:")
  if [ -z "$Line" ]
  then
    echo "# ${Users[$ArrayIndex]} user was not found"
  else
    Uid=$(echo $Line | cut -d: -f3)
    Gid=$(echo $Line | cut -d: -f4)
    UidRef=${Users[$ArrayIndex+1]}
    GidRef=${Users[$ArrayIndex+2]}
    if [ $Uid != $UidRef -o $Gid != $GidRef ]
    then
      echo "# User: ${Users[$ArrayIndex]} uid:$Uid gid:$Gid does not match reference uid:$UidRef gid:$GidRef"
    fi
  fi
done

Read files

read only first line

head -1 myfile.txt

read 5 last lines

tail -5 myfile.txt

read the file without header (first line)

awk 'NR>1' myfile.txt

trap

The format of the trap command is:

# trap 'command_list'  signals

To ignore a signal, use two single quotes in place of the command_list:

# trap ''  signals

To reset a trap use:

# trap ‑ signals

Example

#!/bin/bash
#trapoff_on

trap '' SIGINT SIGQUIT
echo "you cannot terminate using ctrl‑c or ctrl‑\, "
#heavy pressing go on here, cannot interrupt !
sleep 10

trap 'echo terminated; exit' SIGINT SIGQUIT
#user can now interrupt
echo "ok you can now terminate me using those keystrokes"
sleep 10

Example, to remove a file

trap 'rm /tmp/hold∗.$$; exit' SIGNHUP SIGINT SIGQUIT SIGTERM

For info

To view the signals and their default actions (on an AIX machine), view the file:

$ cat /usr/include/sys/signal.h | more
…..
…..
#define SIGHUP     1    /∗ hangup, generated when terminal disconnects ∗/
#define SIGINT     2    /∗ interrupt, generated from terminal special char ∗/
#define SIGQUIT    3    /∗ (∗) quit, generated from terminal special char ∗/
#define SIGILL     4    /∗ (∗) illegal instruction (not reset when caught)∗/
#define SIGTRAP    5    /∗ (∗) trace trap (not reset when caught) ∗/
#define SIGABRT    6    /∗ (∗) abort process ∗/
...

You can use either signal name or signal number.

I have received a signal. Now what?

When a signal has been received by the script, the script can do one of three actions:

  • Ignore it and do nothing. This is probably what most scripts do without the script authors realising it.
  • Catch the signal using trap and take appropriate action.
  • Take the default action.

All the above is true except for the following signals:

  • SIGKILL (signal 9)
  • SIGSTOP(signal 17)
  • SIGCONT (signal 19)
program_lang/bash.txt · Last modified: 2024/04/17 16:06 by manu