2017-03-19 5 views
0

Ich lernte Bash sehr kürzlich, und ich versuche Argumente für mein Skript zu lesen. Also schrieb ich das, aber ich erhalte eine Fehlermeldung (und vim hat in rosa letzten Doppel Klammer in der 4. Zeile highlited)Fehler im Code zum Parsen von Argumenten

#!/bin/bash 
for ((i=1; i<=$#; i++)); do 
    if [[ ${!i:0:1} == "-" ]] && ! [[ ${!i:1} =~ [^a-zA-Z]+ ]]; then 
    for ((j=1; j<=$(($(expr length ${!i})-1)); j++)); do 
     if [[ ${!i:j:1} == "s" ]]; then 
     k=$((i+1)) 
     if [ -e ${!k} ]; then 
      echo $(realpath ${!k}) 
     fi 
     elif [[ ${!i:j:1} == "o" ]]; then 
     echo "Running script without output!" 
     fi 
    done 
    fi 
done 

ich folgende Fehlermeldung erhalten, wenn i ./test -so doc1

./tests2: line 13: syntax error near unexpected token `newline' 
./tests2: line 13: ` done' 

laufen kann Wer hilft mir zu verstehen, was mit meinem Skript nicht stimmt?

+1

Normalerweise, wenn Sie Indizes verwenden, tun Sie etwas falsch. Was versuchst du eigentlich zu erreichen? Es gibt wahrscheinlich eine viel einfachere, viel mehr idiomatische Lösung. – chepner

+0

Ich weiß nicht, was ein Indice ist: S. Aber ich habe nur versucht, nach allen gegebenen Parametern zu suchen, und dann prüfen, ob ein Parameter mehrere Buchstaben enthält, wie "rm -rf ..." –

+0

Lesen Sie auch über den 'getopts'-Befehl in der 'bash'-Manpage . – chepner

Antwort

3

Es sieht tatsächlich so aus, als ob Sie einen Fehler in bash selbst aufgetreten sind!

Bash nicht $(command substitution) zu handhaben, wenn sie innerhalb $((arithmetic expansion)) innerhalb Arithmetik für Schleifen verwendet:

$ for ((; ; $(($(echo 1))))); do echo "running"; break; done 
bash: syntax error near unexpected token `newline' 

Es ist nicht nur ein Problem mit dem zusätzlichen )): bash-Handles, nisten gerade fein:

$ for ((; ; $((1)))); do echo "running"; break; done 
running 

Und Es funktioniert gut mit veralteten Backticks anstelle von $(..)

$ for ((; ; $((`echo 1`)))); do echo "running"; break; done 
running 

Es ist auch innerhalb ((arithmetic commands)) im Allgemeinen in Ordnung, dann ist es für Schleifen nur Arithmetik, die betroffen sind:

$ while (($(($(echo 1))))); do echo "running"; break; done 
running 

Also ja, Gratulation, scheint es ein bash Bug zu sein! Ich weiß nicht, ob dies ein bekanntes Problem ist, aber im Moment können Sie es wie in einem der anderen Posts vorgeschlagen umschreiben, oder verwenden Sie vorzugsweise getopts.

+0

Vielen Dank, dass du ein paar Tests gemacht hast und herausgefunden hast, dass es ein Bug war! Denkst du, ich sollte meinen Beitrag umbenennen zu "potentieller Fehler in for loops (bash)"? –

+0

Natürlich ist eine arithmetische Erweiterung in einer for-Schleife normalerweise nicht notwendig, da die for-Schleife bereits ein arithmetischer Kontext ist. Es gibt also eine einfache Problemumgehung. – rici

+0

Ahhh! Ok, ich verstand immer noch nicht, was diese Doppelklammer bedeutete. Ich verstehe jetzt, dass jene doppelte Klammer, die ich hinzugefügt habe, wo nutzlos ist, und es perfekt ohne sie funktionierte: 'für ((j = 1; j <= $ (Ausdruck Länge $ {! I}) - 1; j ++)); Do' Danke @rici! –

0

Das Problem ist die verschachtelte ((...)) in der inneren for-Schleife. Sie können Ihren Code zu diesem ändern:

#!/bin/bash 
for ((i=1; i<=$#; i++)); do 
    if [[ ${!i:0:1} == "-" ]] && ! [[ ${!i:1} =~ [^a-zA-Z]+ ]]; then 
    lim=$(($(expr length ${!i})-1)) 
    for ((j=1; j<=$lim; j++)); do 
     if [[ ${!i:j:1} == "s" ]]; then 
     k=$((i+1)) 
     if [[ -e ${!k} ]]; then 
      echo $(realpath ${!k}) 
     fi 
     elif [[ ${!i:j:1} == "o" ]]; then 
     echo "Running script without output!" 
     fi 
    done 
    fi 
done 
+0

Also kann ich nicht eine doppelte Klammer in eine andere doppelte Klammer setzen? –

+1

Es scheint so. Ich habe meine Forschung noch nicht gemacht. – codeforester