Übergeben von Optionen/Argumenten/Parametern mit Leerzeichen aus dem Skript an eine Funktion innerhalb

Übergeben von Optionen/Argumenten/Parametern mit Leerzeichen aus dem Skript an eine Funktion innerhalb

Hallo AN ALLE und Danke im Voraus.

Ich habe im Forum nach meiner Situation gesucht und konnte keine Lösung finden. Ich habe ein Skript, an das ich in der Befehlszeile Argumente/Optionen/Parameter übergebe. Einer der Werte enthält ein Leerzeichen, das ich in Anführungszeichen gesetzt habe. Es wäre vielleicht einfacher, ein Beispiel anzugeben. Verzeihen Sie meine Verwendung von Argumenten/Optionen/Parametern.

$:  ./test1.ksh -n -b -d "Home Videos"

Mein Problem besteht darin, eine Variable auf „Home Videos“ zu setzen und sie zusammen zu verwenden. In meinem Beispiel dient -d zur Angabe eines Verzeichnisses. Nicht alle Verzeichnisse haben Leerzeichen, in meinem Fall jedoch einige.

Dies ist ein Beispiel für den Code, der nicht wie erwartet funktioniert.

#!/bin/ksh

Function1()
{
echo "Number of Args in Function1: $#"
echo "Function1 Args: $@"
SetArgs $*
}

SetArgs()
{
echo -e "\nNumber of Args in SetArgs: $#"
echo "SetArgs Args: $@"
while [ $# -gt 0 ]
do
  case $1 in
    -[dD])
    shift
    export DirectoryName=$1
    ;;
    -[nN])
    export Var1=No
    shift
    ;;
    -[bB])
    export Var2=Backup
    shift
    ;;
    *)
    shift
    ;;
  esac
done
Function2
}

Function2()
{
echo "Directory Name: ${DirectoryName}"
}

Function1 $*

Wenn ich dies ausführe, erhalte ich für den Verzeichnisnamen nur „Home“ statt „Home Videos“. Siehe unten.

 $ ./test1.ksh -n -b -d "Home Videos"
 Number of Args in Function1: 5
 Function1 Args: -n -b -d Home Videos

 Number of Args in SetArgs: 5
 SetArgs Args: -n -b -d Home Videos
 Var1 is set to:  No
 Var2 is set to:  Backup
 Directory Name: Home

Was ich erwarte und bisher nicht erreichen konnte, ist:

 $ ./test1.ksh -n -b -d "Home Videos"
 Number of Args in Function1: 4
 Function1 Args: -n -b -d "Home Videos"

 Number of Args in SetArgs: 4
 SetArgs Args: -n -b -d "Home Videos"
 Var1 is set to:  No
 Var2 is set to:  Backup
 Directory Name: Home Videos     <-- Without double quotes in the final usage.

Ich bin für jede Hilfe, die ich hierzu bekommen kann, sehr dankbar ... Ich habe versucht, die Anführungszeichen zu vermeiden, aber ohne Erfolg.

Vielen Dank für die Zeit und Mühe, die Sie mir beim Herausfinden dieser Sache gewidmet haben.

Grüße, Daniel

Antwort1

Mit $*oder $@ohne Anführungszeichenniemalsmacht Sinn.

"$*"ist die Verkettung der Positionsparameter mit dem ersten Zeichen (oder Byte, je nach Shell) von $IFS, "$@"ist die Liste der Positionsparameter.

Ohne Anführungszeichen ist es dasselbe, unterliegt aber Split+Glob (oder nur der Entfernung leerer Elemente mit zsh), wie jede andere Parametererweiterung ohne Anführungszeichen (einige Shells trennen Argumente in $*auch, selbst wenn $IFSes leer ist).

Hier möchten Sie die Liste der Argumente übergebenwie es istzu Ihrer Funktion, also lautet es:

SetArgs "$@"
[...]
Function1 "$@"

Beachten Sie, dass bei ksh88 $IFSdas Leerzeichen enthalten sein muss (was standardmäßig der Fall ist), damit es ordnungsgemäß funktioniert (ein von der Bourne-Shell übernommener Fehler, behoben in ksh93).

Beachten Sie auch, dass bei einigen Implementierungen von ksh(wie älteren Versionen von zshin kshder Emulation)

export DirectoryName=$1

ist ein Split+Glob-Aufruffall. exportist einer dieser Befehle in Korn-ähnlichen Shells, die Shell-Code auswerten könnendurch arithmetische Auswertung in Array-Indizes), so ist eseiner der Fälle, in denen es wichtig ist, Variablen in Anführungszeichen zu setzen, um die Einführung von Schwachstellen bei der Befehlsinjektion zu vermeiden.

Beispiel:

$ (exec -a ksh zsh-4.0.1 -c 'export x=$a' ksh 'foo psvar[0`uname>&2`]')
Linux

Beachten Sie, dass [ $# -gt 0 ]es sich hierbei um einen weiteren Split+Glob-Aufruf handelt, der keinen Sinn ergibt (zumindest mit dem Standardwert von ist es weniger wahrscheinlich, dass er ein Problem darstellt $IFS).

Antwort2

Haben Sie erwogen, den getoptseingebauten Shell-Befehl zu verwenden, um Ihre Argumente zu analysieren (wie z. B. von @Stéphane Chazelas indieser Kommentar)? Das würde Ihnen viel Ärger ersparen.

In Ihrem Fall würde der entsprechende Code wie folgt aussehen:

while getopts "nbd:" argname
do
    case "$argname" in
    n)  Var1="No" ;;
    b)  Var2="Backup" ;;
    d)  DirectoryName ="$OPTARG" ;;
    ?)  echo -e "usage is..."
        exit 1 ;;
    esac
done

verwandte Informationen