Ich habe gerade ein bash
Skript 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, bash
würde ich fragen, ob es eine bessere Möglichkeit gibt, diese Art von Skript zu erstellen (immer noch in bash
der 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,bash
ist 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 cat
Verwenden Sie nichtgrep
, sonderngrep <pattern> <file>
- Warum der Schlaf?
- Entfernen Sie die temporären Variablen, wenn Sie die Dateien nicht benötigen. Verwenden Sie stattdessen Pipes
sort | uniq
kann 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.