Benutzer-Werkzeuge

Webseiten-Werkzeuge


linux:bash_script_snippets

Inhaltsverzeichnis

Bash Snippets für Skripting

Kleine Beispiele für das tägliche Skripting in der Bash Shell.

In welchen Verzeichnis wird das akuelle Script gestartet

In welchen Verzeichnis wird das akuelle Script gestartet:

# Home of the scrips
SCRIPTPATH=$(cd ${0%/*} && echo $PWD/${0##*/})
SCRIPTS=`dirname "$SCRIPTPATH{}"`
export SCRIPTS
 
if [ ! -d ${SCRIPTS} ]; then
   echo "Scripts Directory ${SCRIPTS} not exist"
   echo "May be script not start in bash or over symlink?? "
   exit 1
fi

Beende falls das ermittelte Verzeichnis nicht richtig ist.

Timing und Debugging vom Script

#in Secunden
export PS4='+[${SECONDS}s][${BASH_SOURCE}:${LINENO}]: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'; set -x;
 
 
#in milli Sekunden
N=`date +%s%N`; export PS4='+[$(((`date +%s%N`-$N)/1000000))ms][${BASH_SOURCE}:${LINENO}]: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'; set -x;

see http://stackoverflow.com/questions/18039751/how-to-debug-a-bash-script-and-get-execution-time-per-command

CRS Home in einer Oracle Cluster Umgebung suchen und als lokale Variable verwenden

Über die Datei /etc/oracle/olr.loc kann das Oracle Grid/CRS Home ermittelt werden:

ORACLE_CRS_HOME=$( awk -F= ' /crs_home/ {print $2} ' /etc/oracle/olr.loc )

Aufruf Parameter an ein Script übergeben

Mit getopts die Parameter Übergabe an ein Bash Script im Format „-<buchstabe> <wert>“ implementieren:

# auf die „:“ Syntax für Parameter mit und ohne weiteren Wert achten!
 
usage() { echo "Usage: `basename $0` options -i <inventory nr> / use -h for help" 1>&2 ; exit 1; }
 
typeset COMMAND_PARAM=":i:h"
 
# falls nicht übergeben wurden mit exit beenden
 
if ( ! getopts "${COMMAND_PARAM}" opt); then
 usage
fi
 
# Parameter auswerten
 
while getopts "${COMMAND_PARAM}"  opt; do
  case $opt in
    i)
      echo "-i was triggered, Parameter: $OPTARG " >&2
      inventory=${OPTARG}
      ;;
    h)
      echo "-h was triggered, call help" >&2
      usage
      exit 1
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done
 
 
echo --------------------------------
echo List all hosts from Inventory $inventory
echo --------------------------------

Prüfen ob das Script bereits gestartet wurde

Mit flock überprüfen ob ein Script bereits aktiv ist:

# set ${LOCKFILE} !
# get lock to prevent multiple runs
 
exec 100>${LOCKFILE}_runStat;
 
if flock -n -x 100; then
    echo "Info -- start the script"
 
else
    echo "Error -- Script is still running!"
    exit 1
fi

Nohup

Mit nohup kann ein Script im Hintergrund gestatet werden, dass beim Beenden der Schell weiterläuft.

Falls es bei der Verwendung von nohup zu „hängen“ des startenden Scripts kommt, beachten das alle Pipes ( » $LOGFILE 2>&1 < /dev/null ) auch umgeleitet werden sollten!

..
 # aufruf aus einem Script
 nohup `dirname $0 `/send_message.sh $MY_DATA >> $LOGFILE 2>&1 < /dev/null  &
..

siehe auch ⇒ http://en.wikipedia.org/wiki/Nohup

Auf Existenz in einer if Abfrage prüfen

In der if Abfrage grep aufrufen, Dateiinhalt prüfen, falls nicht gefunden, beenden

if [[ $(grep -c MYFLAG ./template/template.xml) -ne 0 ]]; then
  # tu was
else
    echo "Error -- FLAG not found"
    exit 1
fi
 
# alternativ grep mit Return Wert
 
grep setdb /home/oracle/.profile > /dev/null
 
if [ "$?" -ne "0" ]; then
   echo "The system was not installed with the GPI Oracle default configuration - setdb in .profile is missing - please read the Oracle installation manual."
   exit 1
fi

Datenbank Version prüfen - SQL*Plus Abfragen

Testen ob die DB überhaupt erreichbar ist (ORACLE_SID und ORACLE_HOME müssen in der Umgebung oder zuvor im Script bereits gesetzt werden!).

SQL*Plus aufrufen und mit einer Abfrage die DB Version überprüfen.

#Test if database is running
DB_SMON_PROCESS_ID=`ps -Af | grep  ora_smon_$ORACLE_SID | grep -v grep| wc -l`
 
if [ "${DB_SMON_PROCESS_ID}" = "0" ]; then
  echo "Instance ${ORACLE_SID} is not running (No smon prozess in memory found)"
  echo " "
  exit 6
fi
 
##check Version of Database
 
VERVIEW=\$version
 
ISENTERISE=`echo "set pagesize 0 
set feedback off
select count(*) from v_${VERVIEW} where banner like '%Enterprise%';
quit"|${ORACLE_HOME}/bin/sqlplus -s / as sysdba`
 
echo "check DB Version - Get 1 for EE and 0 for SE - Result is ${ISENTERISE}" 
 
if [ ${ISENTERISE} -eq 1 ] 
then 
#  tue etwas
fi

Für die Versionsabfrage kann auch alternativ folgendes SQL verwendet werden:

SELECT decode( TRIM(LOWER(product)),'oracle database 11g enterprise edition','EE','SE') FROM product_component_version WHERE product LIKE '%atabase%' AND rownum=1;

SQL*Plus für die Ausführung mit EOScipt aufrufen

Parameter werden zuvor im Script erstellt und dann für die SQL Befehle verwandt.

# Run Script to generate Trace of Controlfile
# Run Script to generate Copy of pfile
 
${ORACLE_HOME}/bin/sqlplus / as sysdba << EOScipt
ALTER DATABASE backup controlfile TO trace AS '${BACKUP_DEST}/${ORACLE_DBNAME} controlfile_trace_${DAY_OF_WEEK}.trc' reuse;
CREATE pfile='${BACKUP_DEST}/${ORACLE_DBNAME}/init_${ORACLE_DBNAME}_${DAY_OF_WEEK}.ora' FROM spfile;
exit;
EOScipt

Zweites Beispiel:

printLine    
printLine "Possible data location on the asm instance " "${ORACLE_SID} :"
disktab=\$asm_diskgroup
datalocations=`${ORACLE_HOME}/bin/sqlplus -s / as sysdba << EOScipt
                set pagesize 0
                                set heading  off
                                set feedback off
                select name from v\$disktab group by name;
                exit;
EOScipt`
 
printLineSuccess ${datalocations}

Drittes Beispiel:

printLine "Testing DB Connection to " "${ORACLE_SID} :"
# test CONNECT TO the DB
TEST_CONNECT=`${ORACLE_HOME}/bin/sqlplus -s / as sysdba << EOScipt
                set heading  off
                set pagesize 0
                set feedback off	
                select 'Sucess! DB Connection to '||global_name||' established' from global_name;
                exit;
EOScipt`
 
IF [ "$?" -ne "0" ]; THEN
   echo "Cannot connect to the Oracle DB with the given SID: ${ORACLE_SID} - Fix the DB connection first."
   exit 1
ELSE
    printLineSuccess ${TEST_CONNECT}
fi

!Achtung Der Return Wert von SQL*Plus enthält oft Leerzeichen,die vor einer weiterverarbeitung entfernt werden müssen!

TEST_CONNECTP="${TEST_CONNECT#"${TEST_CONNECT%%[![:space:]]*}"}"
TEST_CONNECT ="${TEST_CONNECT%"${TEST_CONNECT##*[![:space:]]}"}"

Parameter auf einer RAC Umgebung auswerten

Auf einer Oracle RAC Umgebung den Namen des Scanlistener erfragen:

# ScanListenername 
# -- if rac get out the scanlistener name with oracle tools, if not take the db hostname
if [ ${RAC_ENV} = 'true' ]; then
   SCAN_LISTNER=`${ASM_HOME}/bin/srvctl config scan  | head -1 | awk  '{ print($3) }' | sed 's/,//g'`
else
   SCAN_LISTENER=${DBHOST_NAME}
fi
export SCAN_LISTENER

Cluster Name und VIP Nodes ermitteln

# check for cluster enviroment
if [ -f "${ASM_HOME}/bin/cemutlo" ]; then
 
   #Cluster Name
 
   CLUSTER_NAME=`${ASM_HOME}/bin/cemutlo -n`
 
   # List of VIP's
   # todo: 
   # both VIPs can run on one node (if only one node is running)
   # thus giving wrong hostnames for the connection string
 
   VIPNODES=`${ASM_HOME}/bin/srvctl status nodeapps | grep 'VIP' | grep 'on node' | awk '{ print $7 }'`
 
fi  

Liste in eine Komma separierte Zeile umwandeln

Aufgaben: Liste mit ASM Platten inkl. dem + von ASM sortieren, Plus entfernen und mit Komma trennen

# Liste für awk mit /n aufbereiten, sortieren, dupletten entfernen, + ersetzen, /n wieder enfernen, "," einfügen
 
getCommaList () {
  COMMA_LIST=`echo $*|tr " " "\n"|sort|uniq|awk '{ gsub(/+/, "") ; print }'|tr "\n" ","|sed 's/\(.*\),/\1/'`
}
 
# aufruf mit 
getCommaList ${REDOLOG_DEST1} ${REDOLOG_DEST2} ${SYSTEM_TAB_LOC} ${SYSAUX_TAB_LOC}
 
A_PARAMETER_LOCATIONS=${COMMA_LIST}

Array in For Schleife verarbeiten

declare -a VIPNODES
 
VIPNODES[1]="node1"
VIPNODES[2]="node1"
 
 
# impliziet
 
for NODE in ${VIPNODES[@]};
  do
   echo "Info -- export template to ${NODE}"
   # tue etwas mit  ${NODE} 
   # tue etwas
done
 
# mit Zähler
ELEMENT_COUNT=${#VIPNODES[@]}
let "ELEMENT_COUNT=$ELEMENT_COUNT +1"
 
INDEX=1
 
while [ "${INDEX}" -lt "${ELEMENT_COUNT}" ]
do
   echo "Info -- export template to ${VIPNODES[${INDEX}]}"
   # tue etwas mit  ${VIPNODES[${INDEX}]} 
   let "INDEX = $INDEX + 1"
done

Im Array suchen, dazu den Namen das Arrays und den Suchstring übergeben

# create array
MY_VALUES=("srv01" "srv02" "srv03" "srv04")
 
# print array
echo ${MY_VALUES[@]}
 
srv01 srv02 srv03 srv04
 
# search in the index
getIndex() {
   local array="$1[@]"
   local search=$2
   local count=0
   local index=-1
   for ielement in "${!array}"; do
      if [[ $ielement == $search ]]; then
         index=$count
         break
      fi
   let "count = $count + 1"	
   done
   echo $index
}
 
# call the search routine
getIndex MY_VALUES "srv03"
 
2
 
#print the result
echo ${MY_VALUES[2]}
 
# remove this entry
 
unset MY_VALUES[2]
 
# Show all indexes of the array
echo ${!MY_VALUES[@]}
0 1 3
 
# remove the array
unset MY_VALUES
 
# Alternative For loops
 
for i in "${MY_VALUES[*]}"; do echo $i; done
srv01 srv02 srv03 srv04
 
# Watch the missing "
for i in ${MY_VALUES[*]}; do echo $i; done
srv01
srv02
srv02
srv04
 
# Zusammenfassen und deduplizieren
# Putt all SID's in one list
ALL_FOUND_DATABASES=( "${MY_VALUES[@]}" "${MY_VALUES[@]}" )
 
# deduplidate
ALL_DATABASES=( `for i in ${MY_VALUES[@]}; do echo $i; done | sort -u` )

Array Handling see ⇒ http://www.thegeekstuff.com/2010/06/bash-array-tutorial/

String trimmen

Eine String rechts und links bereinigen und alle Zeilenumbrüche entfernen

# Trim a string - remove all whitesapace and ctrl-line feeds
trimString() {
 
	while [ "$1" != "" ]; do
		TRIMSTRING="${TRIMSTRING} ${1}"
		TRIMSTRING="${TRIMSTRING#"${TRIMSTRING%%[![:space:]]*}"}"   
		TRIMSTRING="${TRIMSTRING%"${TRIMSTRING##*[![:space:]]}"}"   
		TRIMSTRING=$(echo ${TRIMSTRING}| /bin/tr -d '\r')
		shift
	done
	echo ${TRIMSTRING}	
}

String vergleichen

text="GPIDB"
if [[ "$text" =~ "DB" ]]; then
   echo "found "
else
   echo "not found"
fi

String bearbeiten

CSV Datei auslesen und verarbeiten

Soll die gesamte Zeile (inkl. Leerzeichen ) als ein String übergeben werden muss der IFS (Internal Field Separator) gesetzt oder readln verwandt werden.
Variante 1 mit IFS auf char(10):

IFS="
"
for CMD in `cat ./input.csv`;
do
# tue etwas mit ${CMD}"
done

Variante 2:

(while read line ; 
do
    # tue etwas mit $line
done ) < input.csv
 

Verarbeite das Änderungsdatum einer Datei in einen Scripts

Mit dem stat befehlt lassen sich alle Datei Eigenschaften einfach auswerten

LASTTOUCH=$(stat -c %y backuo.log)
LASTTOUCH=${MODDATE%% *}
echo $LASTTOUCH

Rechnen mit Date in einen bash Script

Heute minus einen Monat mit einem speziellen Format zurückgeben

date --date "now -1 months" +"%Y-%m-%d %k:%M:00.00000 %:z"

siehe auch ⇒ http://www.unix.com/tips-tutorials/31944-simple-date-time-calulation-bash.html

Auf HP UX geht das natürlich mal wieder nicht ..

Ein tag zurück mit diesem Trick:

DAY_BEFORE=`(export TZ=XYZ+24; date "+%d")`

Password in Config File verschlüsselt ablegen

Ziel ist es das zwar auf der lokalen Maschine das Passwort einfach wieder eingelesen werden kann, aber auf anderen System das Password unlesbar ist.

Hilft nicht sehr das Password auf der lokalen Maschine zu „verstecken“, das Password ist aber in Backups und SVN Verzeichnissen auf anderen Maschinen hinreichend gut geschützt.

PWDFILE=${SCRIPTS_DIR}/password.conf
export PWDFILE
 
# get SYSTEMIDENTIFIER for the encryption of the password
SYSTEMIDENTIFIER=`ls -l /dev/disk/by-uuid/ | awk '{ print $9 }'  | tail -1`
export SYSTEMIDENTIFIER
 
 
###########################################################################
# Password file handling
encryptPWDFile () {
    if [ -f "/usr/bin/openssl" ]; then
        openssl des3 -salt -in  ${PWDFILE} -out ${PWDFILE}.des3 -pass pass:"${SYSTEMIDENTIFIER}" > /dev/null
        #debug printf "%s encrypt file :: \n%s to \n%s.des3 \n" "--" "${PWDFILE}" "${PWDFILE}" 
        rm ${PWDFILE} 
    else
        printError "Openssl not exits - password file will be not encrypted"
 fi
}
 
dencryptPWDFile() {
 if [ -f "/usr/bin/openssl" ]; then
    openssl des3 -d -salt -in ${PWDFILE}.des3 -out ${PWDFILE} -pass pass:"${SYSTEMIDENTIFIER}" > /dev/null
  #debug printf "%s decrypt file :: \n%s.des3 to \n%s \n" "--" "${PWDFILE}" "${PWDFILE}" 
 else
  printError "Openssl not exits - password file will be not dencrypted"
 fi  
}
 
 
## Read encrypted password conf it exits in to memory #########################
 
if [ -f "${PWDFILE}.des3" ]; then
    dencryptPWDFile
    . ${PWDFILE}
    rm ${PWDFILE}
else
  if [ -f "${PWDFILE}" ]; then
        . ${PWDFILE}
        encryptPWDFile
        rm ${PWDFILE}
    else
     printLine "no preconfiguration file =>password.conf<= found"
     echo "export REPOS_PASSWORD=" > ${PWDFILE}
     printLine "no preconfiguration password.conf found - edit the file =>password.conf<= and set password and start again"
     exit 1
    fi
fi

Ja/Nein Abfrage

Den Anwender nach YES oder No fragen, antwortet der Anwender falsch oder gar nicht, bis zu 10-mal wiederholen.

# YES NO Prompt
askYesNo() {
    USER_QUESTION=$1
    QUESTION_DEFAULT=$2    
    if [ ! -n "${QUESTION_DEFAULT}" ]; then
     QUESTION_DEFAULT="NO"
    fi
    LIMIT=10             
    ANSWER_COUNTER=1
    while [ "$ANSWER_COUNTER" -le $LIMIT ]
    do
        printf "   ${USER_QUESTION}   [%s]:" "${QUESTION_DEFAULT}" 
        read YES_NO_ANSWER
        if [ ! -n "${YES_NO_ANSWER}" ]; then
            YES_NO_ANSWER=${QUESTION_DEFAULT}
        fi
        if [ ! -n "${YES_NO_ANSWER}" ]; then
            printError "Please enter a answer for the question :  ${USER_QUESTION}"
        else
           if [ "${YES_NO_ANSWER}" == 'NO' ]; then
              break      
             else
              if [ "${YES_NO_ANSWER}" == 'YES' ]; then
                 break
                else
                 printError "Please enter as answer YES or NO !"
              fi    
      fi                
        fi    
        echo -n "$ANSWER_COUNTER "
        let "ANSWER_COUNTER+=1"
    done  
    if [ ! -n "${YES_NO_ANSWER}" ]; then
        printError "Without a answer  for this question ${USER_QUESTION} for you can not install the schema!"
        exit 1
    fi    
}

Wait mit Fortschrittsanzeige

Normales sleep mit je einen Punkt pro Sekunde um die Wartedauer anzuzeigen:

# wait paramter <seconds> 
waitStart() {
    printLine "Waiting ...for $1 seconds"
    INDEXCOUNTER=0;
    WAITUNTIL=$1
    while [ "$INDEXCOUNTER" -lt "$WAITUNTIL" ]; do 
        printf "*"
        sleep 1
        let "INDEXCOUNTER = $INDEXCOUNTER + 1"
    done
    printf  "%s\n" ""
}

Script immer auf die 0te Sekunde ausführen

Ziel ist es das ein Collector Script immer zu Beginn der 0ten Sekunde das Sammeln startet, zum Beispiel eine I/O Statistik und dann die eingestellte Wartezeit bis zum nächsten Lauf wartet (Wait_Time – Zeit die das Sammeln benötigt!).

WAIT_TIME=10
 
while :
do
    # wait until next x0 seconds reached (sync to every 10,20,30,40,50,00 seconds)
    i=1
    while [ $i -gt 0 ]
    do            
        if [[ ${WAIT_TIME} -gt 9 ]] ; then
            ACTUAL_SECOND=$( /bin/date '+%S' | cut -b2 )
            if [[ $ACTUAL_SECOND -eq 0 ]] ; then
                i=0
            else
                sleep 0.5
            fi    
        fi
    done
 
    # tue etwas
        #
        #
 
        # remember runtime  
    FINISH_SECONDS=$( /bin/date '+%S' | cut -b2 )
    sleep $((${WAIT_TIME}-${FINISH_SECONDS}))
 
done

Java auf einem Linux Server finden und die Version prüfen

Sollen Java Programm aufgerufen werden, stellt sich oft die Frage ob/wo und welche Version installiert ist.

Prüfen mit:

printLine "try to find the java executable and check the version of the java enviroment"
 
which java >  /dev/null 2>&1
 
if [ "$?" == "0" ]; then 
    printLine "found a java executable"
    _java=java
elif [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]];  then
    printLine "found the java executable in enviroment variable JAVA_HOME"
    _java="$JAVA_HOME/bin/java"
else
    printError "no java executable found in your enviroment"
    printError "please set the JAVA_HOME enviroment variable"
 
    printError "no java executable found in your enviroment"
    printError
 
    printError "try to find Java Version from alternatives"
    BEST_ALT_JAVA=`/usr/sbin/alternatives --display java | grep best | awk '{ print $5 }'`
    _java=${BEST_ALT_JAVA/java./java}            
    printError "found Java Version $_java from alternatives"
fi
 
if [[ -x "${_java}" ]]; then 
    printLine "found the java executable ${_java}"            
else
    printError "please set the JAVA_HOME enviroment variable"
    exit 1
fi    
 
 
if [[ "$_java" ]]; then
    version=$("$_java" -version 2>&1 | sed 's/java version "\(.*\)\.\(.*\)\..*"/\1\2/; 1q')
    version_string=$("$_java" -version 2>&1 | awk -F '"' '/version/ {print $2}')
    if (( "$version" > 15 )); then
        printLineSuccess "java version:: $version_string is higher than version 1.5 - OK , software can be used! "
    else         
        printError "check script not support this java version:: $version_string"
        printError "please set the JAVA_HOME enviroment variable to a java home with version 1.6 or higer"
        printError "please remember that set the JAVA_HOME enviroment variable NOT include the bin path!"
        exit 1
    fi
fi

Erkennen ob eine Funktion in der Bash zur Verfügung steht

Mit „declare -f -F“ kann geprüft werden ob eine Funktion exisitert ( Schalter -F verhindert die komplette Ausgabe der Funktion ).

exists() {
    declare -f -F $1 > /dev/null
    return $?
}

Output optimieren

Print Ausgaben über diese Funktionen „optimieren“.

#normal
printLine() {
    if [ ! -n "$1" ]; then
        printf "\033[35m%s\033[0m\n" "----------------------------------------------------------------------------"
    else
        printf "%s" "-- "        
        while [ "$1" != "" ]; do
            printf "%s " $1 
            shift
        done        
        printf  "%s\n" ""
    fi    
}
 
#####################################################################
# 1 Prompt
# 2 list lenght
# 3 seperator
# 4 text
 
printList() {
      printf "%s" "    "        
 
        PRINT_TEXT=${1}    
 
        printf "%s" "${PRINT_TEXT}"
 
        STRG_COUNT=${#PRINT_TEXT}    
 
        while [[  ${STRG_COUNT} -lt $2  ]]; do
         printf "%s" " "
         let "STRG_COUNT+=1"
      done
 
        printf "\033[31m%s \033[0m"   "$3"
        printf "\033[32m%s \033[0m\n" "$4"    
 
}
#####################################################################
#red
printError() {
    if [ ! -n "$1" ]; then
        printf "\033[31m%s\033[0m\n" "----------------------------------------------------------------------------"
    else
        printf "\033[31m%s\033[0m" "!! "        
        while [ "$1" != "" ]; do
            printf "\033[31m%s \033[0m" $1 
            shift
        done
        printf  "%s\n" ""
    fi    
}
#####################################################################
#green
printLineSuccess() {
    if [ ! -n "$1" ]; then
        printf "\033[32m%s\033[0m\n" "----------------------------------------------------------------------------"
    else
        printf "\033[32m%s\033[0m" "!! "        
        while [ "$1" != "" ]; do
            printf "\033[32m%s \033[0m" $1 
            shift
        done
        printf  "%s\n" ""
    fi    
}

Alle Dateien in einem Verzeichnis bearbeiten

In disem Beispiel soll für alle Dateien im Verzeichnis der md5 hash berechnet werden

#!/bin/sh
FILES=/export/*.dmp
LOG_FILE=/export/md5sum_export_files.log
 
echo "Info - check md5 hash to check file integrity  - start at  -- `date` -- " > $LOG_FILE
 
for f in $FILES
do
  echo "Info - get Checksum for file $f ...." >> $LOG_FILE
  #spool md5sum into logfile
  /usr/bin/md5sum $f                          >> $LOG_FILE
done
 
echo "Info - finish at  -- `date` -- "        >> $LOG_FILE

Beispiel für das Löschen aller audit Dump Files im adump Dir aller Datenbanken auf einem Server

In diesen Verzeichnis können sich hunderttausende von Dateien ansammeln, das arbeiten mit einfachen Shell Kommandos wie ls und find wird dann etwas mühsam .-) .

#!/bin/sh
 
 
DIRECTORY=/opt/oracle/admin/*
LOG_FILE=/tmp/aud_delete_logs_list.log
 
 
echo "Info - start to analyses directory :  ${DIRECTORY}  - start at  -- `date` -- "    > $LOG_FILE
 
 
for d in $DIRECTORY
do
 
	FILES=${d}/adump/*.aud
 
	echo "Info - +++++++++++++++++++++++++++++++++++++++++"    >> $LOG_FILE
	echo "Info - check the directory  :  ${FILES} "            >> $LOG_FILE
 
	DATE_NOW_EPOCH=`date +%s`
	#Get the epoch 6 Month ago
	DATE_DELETE_OLDER=`date --date "now -6 months" +"%s"`
 
	echo "Info - check the age of the file - start at  -- `date` -- " >> $LOG_FILE
 
 
	for f in $FILES
	do
	  #File date as epoch 
	  FILE_DATE=`stat -c %Y ${f}`
	  FILE_LOG_DATE=`stat -c %y ${f}`
 
	  if [[ ${FILE_DATE} -lt ${DATE_DELETE_OLDER} ]];
	  then
	   echo "Info - delete :: ${FILE_LOG_DATE} ${f}"  >> $LOG_FILE
	   rm ${f}
	  fi
 
	done
 
	echo "Info - finish with ${FILES} at     -- `date` -- "        >> $LOG_FILE
	echo "Info - +++++++++++++++++++++++++++++++++++++++++"        >> $LOG_FILE
 
done	
 
echo "Info - finish at  -- `date` -- "        >> $LOG_FILE

Spalte mit Zahlen mit AWK aufsummieren

Mit awk '{ sum+=$1 } END { print(„Summe::“ sum) }' jede Zeile aufsummieren und am Ende ausgeben

Beispiel:

In einem Verzeichnis mit Dump Files soll die Größe der Dateien aufsummiert werden:

ls -la *.dmp | awk '{ sum+=$5 } END { print("Summe::" sum) }'

Spalten in einer Log Datei mit hilfe von awk auswerten

Mit der awk Funkction split lassen sich auch einfach zusammen gesetzt werden „zerlegen“.

In diesem Beispiel soll die Häufigkeiten von Waits pro Stunde in Log Writer Logs aufsummiert werden.

# Logfile eintrag in einer Datei mit dem Muster *lgw*:
 
*** 2012-04-02 02:06:09.350
log write elapsed time 1889ms, size 0KB
 
# finde die Dateien und werte das pro stunde aus:
 
find . -name "*_lgwr_*.trc" -mtime -1 -exec grep -H -B 1 "log write elapsed time" {} \; | grep "2013"   | awk '{ split($2,d,"-"); split($3,t,":"); print "|" d[3] "." d[2] "." d[1] " " t[1] ":00" }' | sort | uniq -c
 
 
# erzeugt:
 
      7 |29.04.2013 02:00
     25 |29.04.2013 10:00
     56 |29.04.2013 12:00
     67 |29.04.2013 16:00
     81 |29.04.2013 17:00
    318 |29.04.2013 21:00
     51 |29.04.2013 23:00
 

Schleife für Testdaten

Test Daten in einer Schleife erstellen:

for ((i=1;i<=10000;i++));
do
  echo ${i},AWert${i},BWert${i} >> hdfs_export.csv
done

Statistik mit Zeitstempel versehen

Aufgabe: Statistik auf einem Netzwerk auswerten und mit Zeitstempel speichern:

netstat -i | grep "bond0 "  | awk '{print strftime("%Y-%m-%d %r") ":" $0; }'

Alter einer Datei in Sekunden ermitteln und überschreiben wenn zu alt

Beispiel aus einem Log Script:

.....
 
######### Log file Handling ###########
OVERWRITE="false"
 
# check if a new file must be created
 
#check if file not extis
if [ ! -e $SCRIPTS/${HOST}_${INTERFACE}_${DAY}.log ]; then
  OVERWRITE="true"
else
 
  # check the age of the file
  # if older then one day overwrite
 
  FILEAGE_SECONDS=`date -d "now - $( stat -c "%Y" $SCRIPTS/${HOST}_${INTERFACE}_${DAY}.log ) seconds" +%s`
 
  if [ -z "$FILEAGE_SECONDS"  ]; then 
    FILEAGE_SECONDS=0;
  fi
 
  # if older then one day
  if [ "$FILEAGE_SECONDS" -gt 86400 ]; then
    OVERWRITE="true"
  fi
 
fi
 
# create/overwrite the new file
 
if [ "$OVERWRITE" = "true" ]; then
	echo "---------- start new Day ${DAY} ----------"   >  $SCRIPTS/${HOST}_${INTERFACE}_${DAY}.log 2>&1	
fi
 
....
 

Zeilen eine Log Datei aufrechnen

Wert der Zeile zuvor merken, Variable „zuvor“, mit „NR>1“ erste Zeile weglassen

cat *3.log | awk 'NR>1{print $0 "  -> " $8-zuvor} {zuvor=$8}'
#
cat *.log | awk 'NR>1 { wert=$8-zuvor; if ( wert != 0) eol="  Package Count"; else eol="" ; print $0 "  -> " wert eol } {zuvor=$8}'| grep Package

Wie lange läuft der Linux Prozess schon

getRuntime_of_process.sh
#!/bin/bash
 
gettime () {
	init=`stat -t /proc/$1 | awk '{print $14}'`
	curr=`date +%s`
	seconds=`echo $curr - $init| bc`
	name=`cat /proc/$1/cmdline`
	echo $name $seconds
}
 
 
pidlist=`ps ax | grep -i -E $1 | grep -v grep | awk '{print $1}' | grep -v PID | xargs echo`
 
for pid in $pidlist; do
    gettime $pid
done

Redirect stdout uund stderr und füge das einer Datei hinzu

Mit „» 2>&1“ wird auch Standard Error in das Default log geschrieben.

..
/bin/chmod 666 ${OUTPUT_DIR}/*.txt    >>   ${LOG_FILE}	2>&1
...

12c Cluster Log file mit Tail -f anzeigen

viewCRSlog.sh
#!/bin/sh
 
# set the GRID enviroment with my enviroment setting tool
setdb 1
 
# call adri
# adust patch for your cluster
adrci <<EOF
set home diag/crs/racdb01/crs
show alert -tail -f
EOF

ID's in Export Dateien suchen - Ziel: Fehlende ID's finden

In einer Schnittstelle muss geprüft werden, ob wirklich alle ID's in den Export Dateien vorkommt.

Ziel ist es die ID's zu finden, nicht nicht exportiert wurden.

Zuvor wird eine Liste mit den zu prüfenden ID's erstellt, alle gefundenen ID's werden während des Laufes aus dieser Liste entfernt, es wird mit der ältesten Datei (mit den meisten Datensätzen und damit auch mit dem meisten Treffern begonnen), zum Schluss verbleiben alle fehlenden ID's in der original Liste.

Code:

#!/bin/sh
 
IFS="
"
# read all files
# FILES=./*ORG*.txt
# or get a sorted list over the age of the files
# first files has most matches 
FILES=`ls -ltr *ORG* | awk '{ print $9 }'`
 
RESULT_COUNT=0
MATCH=false
 
#Delete old results
rm ./found_id.txt
touch ./found_id.txt
 
# Loop over all Files in the directroy
for f in $FILES
do
	echo "---------------------"
	echo "-- Info :: Analyse File :: ${f} "
	MATCH=false
	#Loop over all pattern for this file
	# Fist cat  the file to overwirte the file!
	PATTERNLIST=`cat ./org_id.txt`
	#loop
	for PATTERN in $PATTERNLIST
		do		
		RESULT_COUNT=`grep -c ${PATTERN} $f`	
		# if pattern found , remeber the result and remove the pattern from the 
		# serch String
		if [ "${RESULT_COUNT}" != '0' ];
		then
			echo "-- Info :: found :: ${PATTERN}"			
			echo ${PATTERN} >> ./found_id.txt
			# get all NOT in pattern and create with this a new file
                        # here is a bug, not working ...
			# sed -n '/${PATTERN}/!p' ./org_id.txt > ./org_id.tmp
                        # using grep instead of sed
			grep -v "${PATTERN}" ./org_id.txt > ./org_id.tmp
			mv ./org_id.tmp ./org_id.txt
		 fi
	done
done

Liste von Tabellen eines Schemas einfach sichern:

#!/bin/sh
 
declare -a GPI_TABLES
 
GPI_TABLES[1]="T1";
GPI_TABLES[2]="T2";
GPI_TABLES[3]="T3";
GPI_TABLES[4]="T4";
GPI_TABLES[5]="T5";
 
 
for TABLE in ${GPI_TABLES[@]};
  do
    echo "Info -- export table to /tmp/ARCHIVE_TABLE/GPI_${TABLE}.dmp"
	# tue etwas mit  ${TABLE} 
    # tue etwas
    exp GPI/GPI@ORAGPI file=/tmp/ARCHIVE_TABLE/GPI_${TABLE}.dmp LOG=/tmp/ARCHIVE_TABLE/GPI_${TABLE}.log  TABLES=GPI.${TABLE} BUFFER=36000 FEEDBACK=100000
    gzip /tmp/ARCHIVE_TABLE/GPI_${TABLE}.dmp 
done

MD5 Hash eines Verzeichnisses

Für jede Datei den MD5 Hash erzeugen und dann den Hash über die MD5 Hashes

 
find . -type f -exec md5sum {} + | LC_ALL=C sort | md5sum

siehe dazu im Detail ⇒ https://www.baeldung.com/linux/directory-md5-checksum


Liste mit allen SID's des DB Hosts aus der oratab und dem Speicher ermitteln

Liste aller SIDS laufender Datenbanken:

 ps aux  | grep smon_ | grep -v grep | awk '{ print $11 }' | awk -F "_" '{ print $3 }'

Code Beispiel um über die Oratab und über den Speicher die Liste aller aktiven Instanzen auf dem Host zu ermitteln:

# try to find all database on this host over oratab
ALL_CONFIG_DATABASES=`cat /etc/oratab|grep -v "^#"|grep -v "N$"|cut -f1 -d: -s`
 
# try to find all running database on this host if missing in oratab use memory
ALL_RUNING_DATABASES=`ps aux  | grep smon_ | grep -v grep | awk '{ print $11 }' | awk -F "_" '{ print $3 }'`
 
# Putt all SID's in one list
ALL_FOUND_DATABASES=( "${ALL_CONFIG_DATABASES[@]}" "${ALL_RUNING_DATABASES[@]}" )
 
# deduplidate
ALL_DATABASES=( `for i in ${ALL_FOUND_DATABASES[@]}; do echo $i; done | sort -u` )
 
echo Start to read for this SIDs ${ALL_DATABASES[@]} at `date` the alert log
 
for SID in $ALL_DATABASES
do
  # do
  # ... your code with $SID ...
 
done

Finde log4j jars in wars

Finde alle vorkommen von log4j aus bekannten Anlass in allen Wars auf der aktuellen Maschine

files=`find /. -name "*.war"`
for f in $files 
do 
 echo "$HOSTNAME:$f: " 
 unzip -l $f | grep -i log4j | awk -v host="$HOSTNAME" -v war=$f 'BEGIN { OFS = ":" }{ print host,  war,  $4 }'
done

Wann wurde die VM in Betrieb genommen

Auf einer geclonten DB Umgebung ist es gar nicht so einfach zu ermitteln wann das OS installiert wurde.

Ein Ansatz ist mit „stat /“ die „Birth“ Angabe des Filesystems auszuwerten, das kann aber auch leer sein oder nur das inital Datum des Klones zeigen.

In dieser Umgebung ist die Idee, die zugefügten Platten im LV dazu zu anlayiseren:

lvdisplay | grep $HOSTNAME | grep "LV Creation host" | sort -r | awk '{ print $6 " " $7 }' | tail -n 1

Eine Konfigurationdatei Zeilenweise einlesen

Zielenweise in ein Array eine Datei einlesen die z.B. aus mehreren Schemanamen besteht

IFS=$'\n' read -d '' -r -a SCHEMAS  < ${ORACLE_BACKUP_HOME}/export_schemas.conf

Quellen

Tipps und Tricks auf vielen Internet Seiten .-)

Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
"Autor: Gunther Pipperr"
linux/bash_script_snippets.txt · Zuletzt geändert: 2022/07/29 13:31 von gpipperr