linux:bash_script_snippets
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
linux:bash_script_snippets [2018/02/06 15:06] – [ID's in Export Dateien suchen - Ziel: Fehlende ID's finden] gpipperr | linux:bash_script_snippets [2022/07/29 13:31] (aktuell) – [Wann wurde die VM in Betrieb genommen] gpipperr | ||
---|---|---|---|
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/ | ||
+ | SCRIPTS=`dirname " | ||
+ | export SCRIPTS | ||
+ | |||
+ | if [ ! -d ${SCRIPTS} ]; then | ||
+ | echo " | ||
+ | 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 ==== | ||
+ | |||
+ | <code bash> | ||
+ | #in Secunden | ||
+ | export PS4=' | ||
+ | |||
+ | |||
+ | #in milli Sekunden | ||
+ | N=`date +%s%N`; export PS4=' | ||
+ | |||
+ | |||
+ | </ | ||
+ | see http:// | ||
+ | |||
+ | ==== CRS Home in einer Oracle Cluster Umgebung suchen und als lokale Variable verwenden ==== | ||
+ | |||
+ | Über die Datei / | ||
+ | <code bash> | ||
+ | ORACLE_CRS_HOME=$( awk -F= ' /crs_home/ {print $2} ' / | ||
+ | </ | ||
+ | ==== Aufruf Parameter an ein Script übergeben ==== | ||
+ | |||
+ | Mit getopts die Parameter Übergabe an ein Bash Script im Format " | ||
+ | <code bash> | ||
+ | |||
+ | # auf die „:“ Syntax für Parameter mit und ohne weiteren Wert achten! | ||
+ | |||
+ | usage() { echo " | ||
+ | |||
+ | typeset COMMAND_PARAM=": | ||
+ | |||
+ | # falls nicht übergeben wurden mit exit beenden | ||
+ | |||
+ | if ( ! getopts " | ||
+ | usage | ||
+ | fi | ||
+ | |||
+ | # Parameter auswerten | ||
+ | |||
+ | while getopts " | ||
+ | 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 " | ||
+ | exit 1 | ||
+ | ;; | ||
+ | :) | ||
+ | echo " | ||
+ | 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: | ||
+ | |||
+ | <code bash> | ||
+ | |||
+ | # set ${LOCKFILE} ! | ||
+ | # get lock to prevent multiple runs | ||
+ | |||
+ | exec 100> | ||
+ | |||
+ | 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 " | ||
+ | |||
+ | <code bash> | ||
+ | .. | ||
+ | # aufruf aus einem Script | ||
+ | nohup `dirname $0 `/ | ||
+ | .. | ||
+ | |||
+ | </ | ||
+ | |||
+ | siehe auch => http:// | ||
+ | ==== 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 ./ | ||
+ | # tu was | ||
+ | else | ||
+ | echo "Error -- FLAG not found" | ||
+ | exit 1 | ||
+ | fi | ||
+ | |||
+ | # alternativ grep mit Return Wert | ||
+ | |||
+ | grep setdb / | ||
+ | | ||
+ | if [ " | ||
+ | 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. | ||
+ | |||
+ | <code bash> | ||
+ | |||
+ | #Test if database is running | ||
+ | DB_SMON_PROCESS_ID=`ps -Af | grep ora_smon_$ORACLE_SID | grep -v grep| wc -l` | ||
+ | |||
+ | if [ " | ||
+ | echo " | ||
+ | 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 ' | ||
+ | quit" | ||
+ | |||
+ | 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: | ||
+ | <code sql> | ||
+ | select decode( trim(lower(product)),' | ||
+ | </ | ||
+ | |||
+ | ==== 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}/ | ||
+ | ALTER DATABASE backup controlfile TO trace AS ' | ||
+ | CREATE pfile=' | ||
+ | exit; | ||
+ | EOScipt | ||
+ | |||
+ | </ | ||
+ | |||
+ | Zweites Beispiel: | ||
+ | <code sql> | ||
+ | |||
+ | printLine | ||
+ | printLine " | ||
+ | disktab=\$asm_diskgroup | ||
+ | datalocations=`${ORACLE_HOME}/ | ||
+ | set pagesize 0 | ||
+ | set heading | ||
+ | set feedback off | ||
+ | select name from v\$disktab group by name; | ||
+ | exit; | ||
+ | EOScipt` | ||
+ | |||
+ | printLineSuccess ${datalocations} | ||
+ | |||
+ | </ | ||
+ | |||
+ | Drittes Beispiel: | ||
+ | <code sql> | ||
+ | printLine " | ||
+ | # test connect to the DB | ||
+ | TEST_CONNECT=`${ORACLE_HOME}/ | ||
+ | set heading | ||
+ | set pagesize 0 | ||
+ | set feedback off | ||
+ | select ' | ||
+ | exit; | ||
+ | EOScipt` | ||
+ | |||
+ | if [ " | ||
+ | echo " | ||
+ | exit 1 | ||
+ | else | ||
+ | printLineSuccess ${TEST_CONNECT} | ||
+ | fi | ||
+ | </ | ||
+ | |||
+ | **!Achtung** | ||
+ | Der Return Wert von SQL*Plus enthält oft Leerzeichen, | ||
+ | |||
+ | <code bash> | ||
+ | TEST_CONNECTP=" | ||
+ | TEST_CONNECT =" | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== 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} = ' | ||
+ | | ||
+ | else | ||
+ | | ||
+ | fi | ||
+ | export SCAN_LISTENER | ||
+ | </ | ||
+ | |||
+ | Cluster Name und VIP Nodes ermitteln | ||
+ | <code bash> | ||
+ | # check for cluster enviroment | ||
+ | if [ -f " | ||
+ | |||
+ | # | ||
+ | |||
+ | | ||
+ | |||
+ | # 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 | ||
+ | | ||
+ | | ||
+ | |||
+ | fi | ||
+ | </ | ||
+ | ==== 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, | ||
+ | |||
+ | getCommaList () { | ||
+ | COMMA_LIST=`echo $*|tr " " " | ||
+ | } | ||
+ | |||
+ | # aufruf mit | ||
+ | getCommaList ${REDOLOG_DEST1} ${REDOLOG_DEST2} ${SYSTEM_TAB_LOC} ${SYSAUX_TAB_LOC} | ||
+ | |||
+ | A_PARAMETER_LOCATIONS=${COMMA_LIST} | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Array in For Schleife verarbeiten ==== | ||
+ | |||
+ | <code bash> | ||
+ | |||
+ | declare -a VIPNODES | ||
+ | |||
+ | VIPNODES[1]=" | ||
+ | VIPNODES[2]=" | ||
+ | |||
+ | |||
+ | # impliziet | ||
+ | |||
+ | for NODE in ${VIPNODES[@]}; | ||
+ | do | ||
+ | echo "Info -- export template to ${NODE}" | ||
+ | # tue etwas mit ${NODE} | ||
+ | # tue etwas | ||
+ | done | ||
+ | | ||
+ | # mit Zähler | ||
+ | ELEMENT_COUNT=${# | ||
+ | let " | ||
+ | |||
+ | INDEX=1 | ||
+ | |||
+ | while [ " | ||
+ | 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==== | ||
+ | |||
+ | <code bash> | ||
+ | # create array | ||
+ | MY_VALUES=(" | ||
+ | |||
+ | # print array | ||
+ | echo ${MY_VALUES[@]} | ||
+ | |||
+ | srv01 srv02 srv03 srv04 | ||
+ | |||
+ | # search in the index | ||
+ | getIndex() { | ||
+ | local array=" | ||
+ | local search=$2 | ||
+ | local count=0 | ||
+ | local index=-1 | ||
+ | for ielement in " | ||
+ | if [[ $ielement == $search ]]; then | ||
+ | | ||
+ | break | ||
+ | fi | ||
+ | let "count = $count + 1" | ||
+ | done | ||
+ | echo $index | ||
+ | } | ||
+ | |||
+ | # call the search routine | ||
+ | getIndex MY_VALUES " | ||
+ | |||
+ | 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 " | ||
+ | srv01 srv02 srv03 srv04 | ||
+ | |||
+ | # Watch the missing " | ||
+ | for i in ${MY_VALUES[*]}; | ||
+ | srv01 | ||
+ | srv02 | ||
+ | srv02 | ||
+ | srv04 | ||
+ | |||
+ | # Zusammenfassen und deduplizieren | ||
+ | # Putt all SID's in one list | ||
+ | ALL_FOUND_DATABASES=( " | ||
+ | |||
+ | # deduplidate | ||
+ | ALL_DATABASES=( `for i in ${MY_VALUES[@]}; | ||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | Array Handling see => http:// | ||
+ | ==== 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 [ " | ||
+ | TRIMSTRING=" | ||
+ | TRIMSTRING=" | ||
+ | TRIMSTRING=" | ||
+ | TRIMSTRING=$(echo ${TRIMSTRING}| /bin/tr -d ' | ||
+ | shift | ||
+ | done | ||
+ | echo ${TRIMSTRING} | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== String vergleichen ==== | ||
+ | |||
+ | |||
+ | <code bash> | ||
+ | text=" | ||
+ | if [[ " | ||
+ | echo "found " | ||
+ | else | ||
+ | echo "not found" | ||
+ | fi | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== String bearbeiten ==== | ||
+ | |||
+ | siehe => http:// | ||
+ | ==== CSV Datei auslesen und verarbeiten ==== | ||
+ | |||
+ | Soll die gesamte Zeile (inkl. Leerzeichen ) als ein String übergeben werden muss der IFS (Internal Field Separator) | ||
+ | \\ | ||
+ | Variante 1 mit IFS auf char(10): | ||
+ | <code bash> | ||
+ | IFS=" | ||
+ | " | ||
+ | for CMD in `cat ./ | ||
+ | do | ||
+ | # tue etwas mit ${CMD}" | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | Variante 2: | ||
+ | <code bash> | ||
+ | |||
+ | (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" | ||
+ | </ | ||
+ | siehe auch => http:// | ||
+ | |||
+ | 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 " | ||
+ | </ | ||
+ | ==== 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 " | ||
+ | |||
+ | |||
+ | |||
+ | <code bash> | ||
+ | |||
+ | PWDFILE=${SCRIPTS_DIR}/ | ||
+ | export PWDFILE | ||
+ | |||
+ | # get SYSTEMIDENTIFIER for the encryption of the password | ||
+ | SYSTEMIDENTIFIER=`ls -l / | ||
+ | export SYSTEMIDENTIFIER | ||
+ | |||
+ | |||
+ | ########################################################################### | ||
+ | # Password file handling | ||
+ | encryptPWDFile () { | ||
+ | if [ -f "/ | ||
+ | openssl des3 -salt -in ${PWDFILE} -out ${PWDFILE}.des3 -pass pass:" | ||
+ | #debug printf "%s encrypt file :: \n%s to \n%s.des3 \n" " | ||
+ | rm ${PWDFILE} | ||
+ | else | ||
+ | printError " | ||
+ | fi | ||
+ | } | ||
+ | | ||
+ | dencryptPWDFile() { | ||
+ | if [ -f "/ | ||
+ | openssl des3 -d -salt -in ${PWDFILE}.des3 -out ${PWDFILE} -pass pass:" | ||
+ | #debug printf "%s decrypt file :: \n%s.des3 to \n%s \n" " | ||
+ | else | ||
+ | printError " | ||
+ | | ||
+ | } | ||
+ | |||
+ | |||
+ | ## Read encrypted password conf it exits in to memory ######################### | ||
+ | |||
+ | if [ -f " | ||
+ | dencryptPWDFile | ||
+ | . ${PWDFILE} | ||
+ | rm ${PWDFILE} | ||
+ | else | ||
+ | if [ -f " | ||
+ | . ${PWDFILE} | ||
+ | encryptPWDFile | ||
+ | rm ${PWDFILE} | ||
+ | else | ||
+ | | ||
+ | echo " | ||
+ | | ||
+ | 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. | ||
+ | |||
+ | <code bash> | ||
+ | # YES NO Prompt | ||
+ | askYesNo() { | ||
+ | USER_QUESTION=$1 | ||
+ | QUESTION_DEFAULT=$2 | ||
+ | if [ ! -n " | ||
+ | | ||
+ | fi | ||
+ | LIMIT=10 | ||
+ | ANSWER_COUNTER=1 | ||
+ | while [ " | ||
+ | do | ||
+ | printf " | ||
+ | read YES_NO_ANSWER | ||
+ | if [ ! -n " | ||
+ | YES_NO_ANSWER=${QUESTION_DEFAULT} | ||
+ | fi | ||
+ | if [ ! -n " | ||
+ | printError " | ||
+ | else | ||
+ | if [ " | ||
+ | break | ||
+ | else | ||
+ | if [ " | ||
+ | break | ||
+ | else | ||
+ | | ||
+ | fi | ||
+ | fi | ||
+ | fi | ||
+ | echo -n " | ||
+ | let " | ||
+ | done | ||
+ | if [ ! -n " | ||
+ | printError " | ||
+ | exit 1 | ||
+ | fi | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Wait mit Fortschrittsanzeige ==== | ||
+ | |||
+ | Normales sleep mit je einen Punkt pro Sekunde um die Wartedauer anzuzeigen: | ||
+ | <code bash> | ||
+ | # wait paramter < | ||
+ | waitStart() { | ||
+ | printLine " | ||
+ | INDEXCOUNTER=0; | ||
+ | WAITUNTIL=$1 | ||
+ | while [ " | ||
+ | printf " | ||
+ | sleep 1 | ||
+ | let " | ||
+ | done | ||
+ | printf | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== 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, | ||
+ | i=1 | ||
+ | while [ $i -gt 0 ] | ||
+ | do | ||
+ | if [[ ${WAIT_TIME} -gt 9 ]] ; then | ||
+ | ACTUAL_SECOND=$( /bin/date ' | ||
+ | if [[ $ACTUAL_SECOND -eq 0 ]] ; then | ||
+ | i=0 | ||
+ | else | ||
+ | sleep 0.5 | ||
+ | fi | ||
+ | fi | ||
+ | done | ||
+ | | ||
+ | # tue etwas | ||
+ | # | ||
+ | # | ||
+ | | ||
+ | # remember runtime | ||
+ | FINISH_SECONDS=$( /bin/date ' | ||
+ | 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: | ||
+ | <code bash> | ||
+ | printLine "try to find the java executable and check the version of the java enviroment" | ||
+ | |||
+ | which java > /dev/null 2>&1 | ||
+ | |||
+ | if [ " | ||
+ | printLine "found a java executable" | ||
+ | _java=java | ||
+ | elif [[ -n " | ||
+ | printLine "found the java executable in enviroment variable JAVA_HOME" | ||
+ | _java=" | ||
+ | else | ||
+ | printError "no java executable found in your enviroment" | ||
+ | printError " | ||
+ | |||
+ | printError "no java executable found in your enviroment" | ||
+ | printError | ||
+ | | ||
+ | printError "try to find Java Version from alternatives" | ||
+ | BEST_ALT_JAVA=`/ | ||
+ | _java=${BEST_ALT_JAVA/ | ||
+ | printError "found Java Version $_java from alternatives" | ||
+ | fi | ||
+ | |||
+ | if [[ -x " | ||
+ | printLine "found the java executable ${_java}" | ||
+ | else | ||
+ | printError " | ||
+ | exit 1 | ||
+ | fi | ||
+ | | ||
+ | |||
+ | if [[ " | ||
+ | version=$(" | ||
+ | version_string=$(" | ||
+ | if (( " | ||
+ | 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 " | ||
+ | printError " | ||
+ | exit 1 | ||
+ | fi | ||
+ | fi | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Erkennen ob eine Funktion in der Bash zur Verfügung steht ==== | ||
+ | |||
+ | Mit " | ||
+ | |||
+ | |||
+ | <code bash> | ||
+ | |||
+ | exists() { | ||
+ | declare -f -F $1 > /dev/null | ||
+ | return $? | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Output optimieren ==== | ||
+ | |||
+ | Print Ausgaben über diese Funktionen " | ||
+ | |||
+ | <code bash> | ||
+ | #normal | ||
+ | printLine() { | ||
+ | if [ ! -n " | ||
+ | printf " | ||
+ | else | ||
+ | printf " | ||
+ | while [ " | ||
+ | printf "%s " $1 | ||
+ | shift | ||
+ | done | ||
+ | printf | ||
+ | fi | ||
+ | } | ||
+ | |||
+ | ##################################################################### | ||
+ | # 1 Prompt | ||
+ | # 2 list lenght | ||
+ | # 3 seperator | ||
+ | # 4 text | ||
+ | |||
+ | printList() { | ||
+ | printf " | ||
+ | | ||
+ | PRINT_TEXT=${1} | ||
+ | | ||
+ | printf " | ||
+ | | ||
+ | STRG_COUNT=${# | ||
+ | | ||
+ | while [[ ${STRG_COUNT} -lt $2 ]]; do | ||
+ | | ||
+ | let " | ||
+ | done | ||
+ | | ||
+ | printf " | ||
+ | printf " | ||
+ | |||
+ | } | ||
+ | ##################################################################### | ||
+ | #red | ||
+ | printError() { | ||
+ | if [ ! -n " | ||
+ | printf " | ||
+ | else | ||
+ | printf " | ||
+ | while [ " | ||
+ | printf " | ||
+ | shift | ||
+ | done | ||
+ | printf | ||
+ | fi | ||
+ | } | ||
+ | ##################################################################### | ||
+ | #green | ||
+ | printLineSuccess() { | ||
+ | if [ ! -n " | ||
+ | printf " | ||
+ | else | ||
+ | printf " | ||
+ | while [ " | ||
+ | printf " | ||
+ | shift | ||
+ | done | ||
+ | printf | ||
+ | fi | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== 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=/ | ||
+ | LOG_FILE=/ | ||
+ | |||
+ | echo "Info - check md5 hash to check file integrity | ||
+ | |||
+ | for f in $FILES | ||
+ | do | ||
+ | echo "Info - get Checksum for file $f ...." >> $LOG_FILE | ||
+ | #spool md5sum into logfile | ||
+ | / | ||
+ | done | ||
+ | |||
+ | echo "Info - finish at -- `date` -- " | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===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=/ | ||
+ | LOG_FILE=/ | ||
+ | |||
+ | |||
+ | echo "Info - start to analyses directory : ${DIRECTORY} | ||
+ | |||
+ | |||
+ | for d in $DIRECTORY | ||
+ | do | ||
+ | |||
+ | FILES=${d}/ | ||
+ | |||
+ | echo "Info - +++++++++++++++++++++++++++++++++++++++++" | ||
+ | echo "Info - check the directory | ||
+ | |||
+ | DATE_NOW_EPOCH=`date +%s` | ||
+ | #Get the epoch 6 Month ago | ||
+ | DATE_DELETE_OLDER=`date --date "now -6 months" | ||
+ | |||
+ | 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}" | ||
+ | rm ${f} | ||
+ | fi | ||
+ | |||
+ | done | ||
+ | |||
+ | echo "Info - finish with ${FILES} at -- `date` -- " | ||
+ | echo "Info - +++++++++++++++++++++++++++++++++++++++++" | ||
+ | |||
+ | done | ||
+ | |||
+ | echo "Info - finish at -- `date` -- " | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Spalte mit Zahlen mit AWK aufsummieren ==== | ||
+ | |||
+ | Mit **awk '{ sum+=$1 } END { print(" | ||
+ | |||
+ | 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(" | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Spalten in einer Log Datei mit hilfe von awk auswerten ==== | ||
+ | |||
+ | Mit der awk Funkction **split** lassen sich auch einfach zusammen gesetzt werden " | ||
+ | |||
+ | 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: | ||
+ | log write elapsed time 1889ms, size 0KB | ||
+ | |||
+ | # finde die Dateien und werte das pro stunde aus: | ||
+ | |||
+ | find . -name " | ||
+ | |||
+ | |||
+ | # 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: | ||
+ | |||
+ | <code bash> | ||
+ | for ((i=1; | ||
+ | do | ||
+ | echo ${i}, | ||
+ | done | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Statistik mit Zeitstempel versehen ==== | ||
+ | |||
+ | Aufgabe: Statistik auf einem Netzwerk auswerten und mit Zeitstempel speichern: | ||
+ | |||
+ | <code bash> | ||
+ | netstat -i | grep "bond0 " | ||
+ | |||
+ | </ | ||
+ | |||
+ | === Alter einer Datei in Sekunden ermitteln und überschreiben wenn zu alt=== | ||
+ | |||
+ | Beispiel aus einem Log Script: | ||
+ | |||
+ | <code bash> | ||
+ | ..... | ||
+ | |||
+ | ######### Log file Handling ########### | ||
+ | OVERWRITE=" | ||
+ | |||
+ | # check if a new file must be created | ||
+ | |||
+ | #check if file not extis | ||
+ | if [ ! -e $SCRIPTS/ | ||
+ | OVERWRITE=" | ||
+ | else | ||
+ | |||
+ | # check the age of the file | ||
+ | # if older then one day overwrite | ||
+ | |||
+ | FILEAGE_SECONDS=`date -d "now - $( stat -c " | ||
+ | | ||
+ | if [ -z " | ||
+ | FILEAGE_SECONDS=0; | ||
+ | fi | ||
+ | | ||
+ | # if older then one day | ||
+ | if [ " | ||
+ | OVERWRITE=" | ||
+ | fi | ||
+ | | ||
+ | fi | ||
+ | |||
+ | # create/ | ||
+ | |||
+ | if [ " | ||
+ | echo " | ||
+ | fi | ||
+ | | ||
+ | .... | ||
+ | | ||
+ | </ | ||
+ | |||
+ | ==== Zeilen eine Log Datei aufrechnen ==== | ||
+ | |||
+ | Wert der Zeile zuvor merken, Variable " | ||
+ | |||
+ | <code bash> | ||
+ | cat *3.log | awk ' | ||
+ | # | ||
+ | cat *.log | awk ' | ||
+ | </ | ||
+ | |||
+ | ==== Wie lange läuft der Linux Prozess schon ==== | ||
+ | |||
+ | <code bash getRuntime_of_process.sh> | ||
+ | |||
+ | #!/bin/bash | ||
+ | |||
+ | gettime () { | ||
+ | init=`stat -t /proc/$1 | awk ' | ||
+ | curr=`date +%s` | ||
+ | seconds=`echo $curr - $init| bc` | ||
+ | name=`cat / | ||
+ | echo $name $seconds | ||
+ | } | ||
+ | |||
+ | |||
+ | pidlist=`ps ax | grep -i -E $1 | grep -v grep | awk ' | ||
+ | |||
+ | for pid in $pidlist; do | ||
+ | gettime $pid | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ====Redirect stdout uund stderr und füge das einer Datei hinzu==== | ||
+ | |||
+ | Mit <fc # | ||
+ | |||
+ | <code bash> | ||
+ | .. | ||
+ | /bin/chmod 666 ${OUTPUT_DIR}/ | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== 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/ | ||
+ | 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: | ||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | |||
+ | IFS=" | ||
+ | " | ||
+ | # read all files | ||
+ | # FILES=./ | ||
+ | # 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 ./ | ||
+ | touch ./ | ||
+ | |||
+ | # 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 ./ | ||
+ | #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 [ " | ||
+ | then | ||
+ | echo "-- Info :: found :: ${PATTERN}" | ||
+ | echo ${PATTERN} >> ./ | ||
+ | # get all NOT in pattern and create with this a new file | ||
+ | # here is a bug, not working ... | ||
+ | # sed -n '/ | ||
+ | # using grep instead of sed | ||
+ | grep -v " | ||
+ | mv ./ | ||
+ | fi | ||
+ | done | ||
+ | done | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | Liste von Tabellen eines Schemas einfach sichern: | ||
+ | |||
+ | <code bash> | ||
+ | |||
+ | #!/bin/sh | ||
+ | |||
+ | declare -a GPI_TABLES | ||
+ | |||
+ | GPI_TABLES[1]=" | ||
+ | GPI_TABLES[2]=" | ||
+ | GPI_TABLES[3]=" | ||
+ | GPI_TABLES[4]=" | ||
+ | GPI_TABLES[5]=" | ||
+ | |||
+ | |||
+ | for TABLE in ${GPI_TABLES[@]}; | ||
+ | do | ||
+ | echo "Info -- export table to / | ||
+ | # tue etwas mit ${TABLE} | ||
+ | # tue etwas | ||
+ | exp GPI/ | ||
+ | gzip / | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== MD5 Hash eines Verzeichnisses ==== | ||
+ | |||
+ | |||
+ | Für jede Datei den MD5 Hash erzeugen und dann den Hash über die MD5 Hashes | ||
+ | |||
+ | <code bash> | ||
+ | |||
+ | |||
+ | find . -type f -exec md5sum {} + | LC_ALL=C sort | md5sum | ||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | siehe dazu im Detail => https:// | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ==== Liste mit allen SID's des DB Hosts aus der oratab und dem Speicher ermitteln ==== | ||
+ | |||
+ | Liste aller SIDS laufender Datenbanken: | ||
+ | <code bash> | ||
+ | ps aux | grep smon_ | grep -v grep | awk '{ print $11 }' | awk -F " | ||
+ | </ | ||
+ | |||
+ | Code Beispiel um über die Oratab und über den Speicher die Liste aller aktiven Instanzen auf dem Host zu ermitteln: | ||
+ | <code bash> | ||
+ | |||
+ | # try to find all database on this host over oratab | ||
+ | ALL_CONFIG_DATABASES=`cat / | ||
+ | |||
+ | # 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 " | ||
+ | |||
+ | # Putt all SID's in one list | ||
+ | ALL_FOUND_DATABASES=( " | ||
+ | |||
+ | # deduplidate | ||
+ | ALL_DATABASES=( `for i in ${ALL_FOUND_DATABASES[@]}; | ||
+ | |||
+ | 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 | ||
+ | <code bash> | ||
+ | files=`find /. -name " | ||
+ | for f in $files | ||
+ | do | ||
+ | echo " | ||
+ | unzip -l $f | grep -i log4j | awk -v host=" | ||
+ | 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 " | ||
+ | |||
+ | In dieser Umgebung ist die Idee, die zugefügten Platten im LV dazu zu anlayiseren: | ||
+ | <code bash> | ||
+ | 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 | ||
+ | |||
+ | <code bash> | ||
+ | IFS=$' | ||
+ | </ | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ====Quellen==== | ||
+ | |||
+ | |||
+ | Tipps und Tricks auf vielen Internet Seiten .-) | ||
+ | |||
linux/bash_script_snippets.txt · Zuletzt geändert: 2022/07/29 13:31 von gpipperr