===== 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 .-)