Benutzer-Werkzeuge

Webseiten-Werkzeuge


linux:bash_script_snippets

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
linux:bash_script_snippets [2018/02/06 15:06]
gpipperr [ID's in Export Dateien suchen - Ziel: Fehlende ID's finden]
linux:bash_script_snippets [2019/02/21 15:21] (aktuell)
gpipperr [Beispiel für das Löschen aller audit Dump Files im adump Dir einer Datenbank]
Zeile 1: Zeile 1:
 +===== 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:
 +<code bash>
 +# 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
 +</code>
 +
 +Beende falls das ermittelte Verzeichnis nicht richtig ist.
 +
 +==== Timing und Debugging vom Script ==== 
 +
 +<code bash>
 +#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;
 +
 +
 +</code>
 +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:
 +<code bash>
 +ORACLE_CRS_HOME=$( awk -F= ' /crs_home/ {print $2} ' /etc/oracle/olr.loc )
 +</code>
 +==== Aufruf Parameter an ein Script übergeben ==== 
 +
 +Mit getopts die Parameter Übergabe an ein Bash Script im Format "-<buchstabe> <wert>" implementieren:
 +<code bash>
 +
 +# auf die „:“ Syntax für Parameter mit und ohne weiteren Wert achten!
 +
 +typeset COMMAND_PARAM=":a:h"
 +
 +# falls nicht übergeben wurden mit exit beenden
 +if ( ! getopts "${COMMAND_PARAM}" opt); then
 +    echo "Usage: `basename $0` options -a <filename> / use -h for help";
 +    exit 1;
 +fi
 + 
 +# Parameter auswerten
 +
 +while getopts "${COMMAND_PARAM}"  opt; do
 +  case $opt in
 +    a)
 +      echo "-a was triggered, Parameter: $OPTARG " >&2
 +      ;;
 +    h)
 +      echo "-h was triggered, call help" >&2
 +      ;;  
 +    \?)
 +      echo "Invalid option: -$OPTARG" >&2
 +      exit 1
 +      ;;
 +    :)
 +      echo "Option -$OPTARG requires an argument." >&2
 +      exit 1
 +      ;;
 +  esac
 +done
 +
 +</code>
 +
 +==== Prüfen ob das Script bereits gestartet wurde ==== 
 +
 +Mit flock  überprüfen ob ein Script bereits aktiv ist:
 +
 +<code bash>
 +
 +# 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
 +
 +</code>
 +
 +==== 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!
 +
 +<code bash>
 +..
 + # aufruf aus einem Script
 + nohup `dirname $0 `/send_message.sh $MY_DATA >> $LOGFILE 2>&1 < /dev/null  &
 +..
 +
 +</code>
 +
 +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
 +<code bash>
 +
 +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
 +</code>
 +
 +
 +
 +==== 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.
 +
 +<code bash>
 +
 +#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
 +
 +</code>
 +Für die Versionsabfrage kann auch alternativ folgendes SQL verwendet werden:
 +<code sql>
 +select decode( trim(lower(product)),'oracle database 11g enterprise edition','EE','SE') from product_component_version where product like '%atabase%' and rownum=1;
 +</code>
 +
 +==== SQL*Plus für die Ausführung mit EOScipt aufrufen ==== 
 +
 +Parameter werden zuvor im Script erstellt und dann für die SQL Befehle verwandt.
 +
 +<code bash>
 +
 +# 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
 +
 +</code>
 +
 +Zweites Beispiel:
 +<code sql>
 +
 +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}
 +
 +</code>
 +
 +Drittes Beispiel:
 +<code sql>
 +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
 +</code>
 +
 +**!Achtung**
 +Der Return Wert von SQL*Plus enthält oft Leerzeichen,die vor einer weiterverarbeitung entfernt werden müssen!
 +
 +<code bash>
 +TEST_CONNECTP="${TEST_CONNECT#"${TEST_CONNECT%%[![:space:]]*}"}"
 +TEST_CONNECT ="${TEST_CONNECT%"${TEST_CONNECT##*[![:space:]]}"}"
 +</code>
 +
 +
 +
 +
 +
 +==== Parameter auf einer RAC Umgebung auswerten ==== 
 +
 +Auf einer Oracle RAC Umgebung den Namen des Scanlistener erfragen:
 +<code bash>
 +# 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
 +</code>
 +
 +Cluster Name und VIP Nodes ermitteln
 +<code bash>
 +# 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  
 +</code>
 +==== Liste in eine Komma separierte Zeile umwandeln ==== 
 +
 +Aufgaben: Liste mit ASM Platten inkl. dem + von ASM sortieren, Plus entfernen und mit Komma trennen
 +<code bash>
 +
 +# 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}
 +
 +</code>
 +
 +==== Array in For Schleife verarbeiten ==== 
 +
 +<code bash>
 +
 +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
 +
 +
 +</code>
 +
 +
 +==== Im Array suchen, dazu den Namen das Arrays und den Suchstring übergeben==== 
 +
 +<code bash>
 +# 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
 +
 +</code>
 +
 +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
 +<code bash>
 +# 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}
 +}
 +
 +</code>
 +
 +==== String vergleichen ==== 
 +
 +
 +<code bash>
 +text="GPIDB"
 +if [[ "$text" =~ "DB" ]]; then
 +   echo "found "
 +else
 +   echo "not found"
 +fi
 +</code>
 +
 +
 +==== String bearbeiten ==== 
 +
 +siehe => http://tldp.org/LDP/abs/html/string-manipulation.html
 +==== 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):
 +<code bash>
 +IFS="
 +"
 +for CMD in `cat ./input.csv`;
 +do
 +# tue etwas mit ${CMD}"
 +done
 +</code>
 +
 +Variante 2:
 +<code bash>
 +
 +(while read line ; 
 +do
 +    # tue etwas mit $line
 +done ) < input.csv
 +  
 +</code>
 +==== Verarbeite das Änderungsdatum einer Datei in einen Scripts ==== 
 +Mit dem stat befehlt lassen sich alle Datei Eigenschaften einfach auswerten
 +<code>
 +LASTTOUCH=$(stat -c %y backuo.log)
 +LASTTOUCH=${MODDATE%% *}
 +echo $LASTTOUCH
 +</code>
 +
 +==== Rechnen mit Date in einen bash Script ==== 
 +Heute minus einen Monat mit einem speziellen Format zurückgeben
 +<code>
 +date --date "now -1 months" +"%Y-%m-%d %k:%M:00.00000 %:z"
 +</code>
 +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:
 +<code bash>
 +DAY_BEFORE=`(export TZ=XYZ+24; date "+%d")`
 +</code>
 +==== 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.
 +
 +
 +
 +<code bash>
 +
 +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
 +
 +
 +</code>
 +
 +
 +==== Ja/Nein Abfrage ==== 
 +Den Anwender nach YES oder No fragen, antwortet der Anwender falsch oder gar nicht, bis zu 10-mal wiederholen.
 +
 +<code bash>
 +# 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    
 +}
 +</code>
 +
 +==== Wait mit Fortschrittsanzeige ==== 
 +
 +Normales sleep mit je einen Punkt pro Sekunde um die Wartedauer anzuzeigen:
 +<code bash>
 +# 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" ""
 +}
 +</code>
 +
 +==== 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!).
 +
 +<code bash>
 +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
 +</code>
 +
 +==== 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:
 +<code bash>
 +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
 +
 +</code>
 +
 +==== 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 ).
 +
 +
 +<code bash>
 +
 +exists() {
 +    declare -f -F $1 > /dev/null
 +    return $?
 +}
 +
 +</code>
 +
 +==== Output optimieren ==== 
 +
 +Print Ausgaben über diese Funktionen "optimieren".
 +
 +<code bash>
 +#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    
 +}
 +</code>
 +
 +==== Alle Dateien in einem Verzeichnis bearbeiten ====
 +
 +In disem Beispiel soll für alle Dateien im Verzeichnis der md5 hash berechnet werden
 +
 +<code bash>
 +
 +#!/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
 +
 +</code>
 +
 +===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 .-) .
 +
 +
 +<code bash>
 +
 +#!/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
 +
 +</code>
 +
 +
 +==== 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:
 +
 +<code bash>
 +ls -la *.dmp | awk '{ sum+=$5 } END { print("Summe::" sum) }'
 +</code>
 +
 +
 +==== 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.
 +
 +
 +<code bash>
 +
 +# 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
 +     
 +</code>
 +
 +==== Schleife für Testdaten ==== 
 +
 +Test Daten in einer Schleife erstellen:
 +
 +<code bash>
 +for ((i=1;i<=10000;i++));
 +do
 +  echo ${i},AWert${i},BWert${i} >> hdfs_export.csv
 +done
 +
 +</code>
 +
 +==== Statistik mit Zeitstempel versehen ==== 
 +
 +Aufgabe: Statistik auf einem Netzwerk auswerten und mit Zeitstempel speichern:
 +
 +<code bash>
 +netstat -i | grep "bond0 "  | awk '{print strftime("%Y-%m-%d %r") ":" $0; }'
 +
 +</code>
 +
 +=== Alter einer Datei in Sekunden ermitteln und überschreiben wenn zu alt===
 +
 +Beispiel aus einem Log Script:
 +
 +<code bash>
 +.....
 +
 +######### 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
 +  
 +....
 +  
 +</code>
 +
 +==== Zeilen eine Log Datei aufrechnen ==== 
 +
 +Wert der Zeile zuvor merken, Variable "zuvor", mit "NR>1" erste Zeile weglassen
 +
 +<code bash>
 +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
 +</code>
 +
 +==== Wie lange läuft der Linux Prozess schon ====
 +
 +<code bash 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
 +</code>
 +
 +
 +----
 +
 +====Redirect stdout uund stderr und füge das einer Datei hinzu====
 +
 +Mit <fc #800000>">> 2>&1"</fc> wird auch Standard Error in das Default log geschrieben.
 +
 +<code bash>
 +..
 +/bin/chmod 666 ${OUTPUT_DIR}/*.txt    >>   ${LOG_FILE} 2>&1
 +...
 +</code>
 +
 +
 +----
 +
 +==== 12c Cluster Log file mit Tail -f anzeigen====
 +
 +<code bash 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
 +</code>
 +
 +
 +
 +----
 +
 +
 +==== 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:
 +<code bash>
 +#!/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
 +
 +</code>
 +
 +
 +----
 +
 +Liste von Tabellen eines Schemas einfach sichern:
 +
 +<code bash>
 +
 +#!/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
 +</code>
 +
 +====Quellen====
 +
 +
 +Tipps und Tricks auf vielen Internet Seiten .-)
 +
  
"Autor: Gunther Pipperr"
linux/bash_script_snippets.txt · Zuletzt geändert: 2019/02/21 15:21 von gpipperr