===== 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 "- " implementieren:
# auf die „:“ Syntax für Parameter mit und ohne weiteren Wert achten!
usage() { echo "Usage: `basename $0` options -i / 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 ====
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):
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
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 ====
#!/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====
#!/bin/sh
# set the GRID enviroment with my enviroment setting tool
setdb 1
# call adri
# adust patch for your cluster
adrci <
----
==== 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 .-)