it-swarm.com.de

Bash löst Fehler aus, Zeile 8: $ 1: ungebundene Variable

Ich versuche zu lernen, wie man getopts verwendet, damit ich Skripte mit analysierter Eingabe haben kann (obwohl ich denke, dass getopts besser sein könnte). Ich versuche nur ein einfaches Skript zu schreiben, um die Prozentsätze der Partitionsnutzung zurückzugeben. Das Problem ist, dass eine meiner Bash-Funktionen nicht zu mögen scheint, dass ich $1 Als Variable innerhalb der Funktion referenziere. Der Grund, warum ich auf $1 Verweise, ist, dass der Funktion get_percent Ein Mountpunkt als optionales Argument übergeben werden kann, das anstelle aller Mountpunkte angezeigt werden soll.

Das Skript

#!/usr/bin/bash

set -e
set -u
set -o pipefail

get_percent(){
    if [ -n "$1" ] 
    then
        df -h $1 | tail -n +2 | awk '{ print $1,"\t",$5 }'
    else
        df -h | tail -n +2 | awk '{ print $1,"\t",$5 }'
    fi
}

usage(){
    echo "script usage: $(basename $0) [-h] [-p] [-m mount_point]" >&2
}

# If the user doesn't supply any arguments, we run the script as normal
if [ $# -eq 0 ];
then
    get_percent
    exit 0
fi
# ...

Die Ausgabe

$ bash thing.sh
thing.sh: line 8: $1: unbound variable

$ bash -x thing.sh
+ set -e
+ set -u
+ set -o pipefail
+ '[' 0 -eq 0 ']'
+ get_percent
thing.sh: line 8: $1: unbound variable
15
Timothy Pulliam

set -u wird genau so abgebrochen, wie Sie es beschreiben, wenn Sie auf eine Variable verweisen, die nicht festgelegt wurde. Sie rufen Ihr Skript ohne Argumente auf, also get_percent wird ohne Argumente aufgerufen, wodurch $1 nicht gesetzt sein.

Überprüfen Sie dies entweder, bevor Sie Ihre Funktion aufrufen, oder verwenden Sie Standarderweiterungen (${1-default} wird auf default erweitert, falls nicht bereits etwas anderes festgelegt ist).

29
DopeGhoti

Dies ist der Effekt von set -u.

Sie können $# In der Funktion überprüfen und vermeiden, auf $1 Zu verweisen, wenn diese nicht festgelegt ist.

Mit $# Können Sie auf die Anzahl der Parameter zugreifen. Im globalen Kontext ist es die Anzahl der Parameter für das Skript, in einer Funktion die Anzahl der Parameter für die Funktion.

Im Kontext der Frage ist es

if [ $# -ge 1 ] && [ -n "$1" ]
then
    df -h $1 | tail -n +2 | awk '{ print $1,"\t",$5 }'
else
    df -h | tail -n +2 | awk '{ print $1,"\t",$5 }'
fi

Beachten Sie, dass Sie [ $# -ge 1 ] && [ -n "$1" ] Und nicht [ $# -ge 1 -a -n "$1" ] Verwenden müssen, da dies zuerst $1 Auswerten und dann $# Aktivieren würde.

6
RalfFriedl

Da dies bash ist, können Sie die Prüfung auf $1 Umgehen und einfach "[email protected]" Verwenden ($1 Ist der erste Parameter, [email protected]). ist alles von ihnen; wenn es in doppelten Anführungszeichen steht, verschwindet es vollständig, wenn es keine Werte hat, wodurch vermieden wird, dass es von set -u abgefangen wird:

get_percent() {
    df -h "[email protected]" | awk 'NR>1 { printf "%s\t%s\n", $1, $5 }'
}

Ich habe auch den Rest der Zeile leicht angepasst, damit zwischen den beiden von Ihnen ausgegebenen Werten kein {Leerzeichen} {Tab} {Leerzeichen} angezeigt wird, sondern nur ein {Tab}. Wenn Sie die beiden unsichtbaren Leerzeichen wirklich möchten, ändern Sie awk in printf "%s \t %s\n", $1, $5.

3
roaima