Best Practice für BASH-Skripte

Best Practice für BASH-Skripte

Ich habe gerade ein bashSkript geschrieben und es funktioniert wie gewünscht. Das ist das Skript:

#!/usr/bin/env bash
DY=`date +%Y%m%d`

gunzip -c /var/log/cisco/cisco.log-$DY.gz > file.log
sleep 3
cat file.log | grep "Virtual device ath0 asks to queue packet" > file2.log
awk '{print $4}' file2.log > IP.log
sort IP.log | uniq > devices.log
wc -l devices.log
rm file.log file2.log IP.log devices.log

Da ich jedoch neu bin, bashwürde ich fragen, ob es eine bessere Möglichkeit gibt, diese Art von Skript zu erstellen (immer noch in bashder Umgebung). Alle Erklärungen werden sehr hilfreich sein, um mein Lernen zu verbessern.

Antwort1

  • Verwenden Sie eine kommentierte Überschrift, die erklärt, was das Skript macht und wofür es verwendet wird
  • Verwenden Sie die POSIX-Shell ( /bin/sh) aus Portabilitätsgründen, bashist für einfache Skripte oft nicht erforderlich
  • Verwenden Sie Variablen anstelle von fest codierten Zeichenfolgen
  • Erwägen Sie die Verwendung der $(some_command)Syntax anstelle von Backticks
  • catVerwenden Sie nicht grep, sonderngrep <pattern> <file>
  • Warum der Schlaf?
  • Entfernen Sie die temporären Variablen, wenn Sie die Dateien nicht benötigen. Verwenden Sie stattdessen Pipes
  • sort | uniqkann ersetzt werden durchsort -u
  • Wenn Sie temporäre Dateien verwenden müssen, berücksichtigen Sierichtig aufräumen.

Antwort2

Hier ist eine Variante Ihres Skripts als „Einzeiler“:

gunzip -c /var/log/cisco/cisco.log-$(date +%Y%m%d).gz | \
grep "Virtual device ath0 asks to queue packet" | \
awk '{print $4}' | sort | uniq | wc -l

Es wird vermieden, temporäre Zwischendateien zu erstellen, dieMaischneller sein. Wenn Sie diese Zwischendateien jedoch brauchen oder verwenden möchten, ist der Einzeiler die schlechtere Lösung.

Eines der Dinge, die ich durch das Lesen einiger gut geschriebener Shell-Skripte gelernt habe, ist, dass die Sequenz „grep | awk“ oft kombiniert werden kann. Beachten Sie, dass in Ihrem Skript der Befehl grep ersetzt wurde:

gunzip -c /var/log/cisco/cisco.log-$(date +%Y%m%d).gz | \
awk '/Virtual device ath0 asks to queue packet/ { print $4 }' | \
sort | uniq | wc -l

Antwort3

Ich habe es kürzlich als hilfreich empfunden,Inoffizieller strikter Bash-Modus:

#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

Dieser Parametersatz trägt unter anderem dazu bei, Überraschungen durch nicht festgelegte Variablen zu reduzieren.

verwandte Informationen