[Bash] bij gebruik van $* gaan namen met spaties verloren?

Pagina: 1
Acties:

  • A_L
  • Registratie: Juni 2001
  • Niet online
Ik heb een bash-script gemaakt dat zichzelf recursief aanroept.
Het roept zichzelf weer aan met een door "shift" 1 ingekorte parameter lijst.
hieronder een (ingekort) voorbeeld van het programma.

code:
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
MINARGS=1
! [ $# -lt $MINARGS ] || exit 65 # 1 of meer argumenten vereist

if [ $# -eq $MINARGS ]; then #als er nog 1 parameter is
    echo "$1"
else
    echo "$1" #eerste keer hier goed omdat ik hiervoor geen $* gebruik
    shift #argumenten lijst naar links doorschuiven
    $0 $* #recursive call <- Hiermee gaan lange namen verloren
fi


Het probleem is dat (bestands)namen met spaties door $* worden opgevat als losse elementen.
bijvoorbeeld:

code:
1
2
3
4
5
6
7
8
9
[A_L@localhost:~]$ testprogramma "1 2 3" "Lange Bestands naam" "4 5 6"
1 2 3
Lange
Bestands
naam
4
5
6
[A_L@localhost:~]$


zelfs dit werkt niet:
code:
1
2
3
4
for archive in $*
do
    echo "$archive"
done


Mijn vraag is dus of iemand weet of dit normaal is. Of dat ik wat over het hoofd zie.
Of dat je $* helemaal niet voor namen met spaties kunt gebruiken.
("$*" plakt alle argumenten aan elkaar als 1 lange string, dus dat gaat ook niet :) )


P.S. Ik weet inmiddels wel dat het zo wel werkt:
code:
1
2
3
4
5
until [ -z "$1" ] # Until all parameters used up...
do
        echo "$1"
    shift
done

  • XTerm
  • Registratie: Juli 2001
  • Laatst online: 10-06-2025
Bash en messy bestandsnamen is een *hel*.
Ik heb de volgende redelijk klungelige oplossing :
code:
1
2
3
4
5
6
#!/bin/bash
IFS=$(echo -en \\n\\t)
export IFS
v=`echo $1 | sed -e 's/"//g'`
for f in `ls $v`; do
done


Daarmee vermijd je het probleem EN kan je bestanden selecteren.
Stel je wil alle bestandsnamen die met een A of een B beginnen dan roep je het script aan met :
code:
1
./script \"[A-B]*\"

Wat er dan tusse de \" \" staat wordt als argument meegegeven aan ls, en door je IFS te veranderen kapt ie af bij newlines.

  • RikY
  • Registratie: Januari 2000
  • Laatst online: 01-03 16:57
Gebruik "$@" ipv $*

Uit man bash:
* Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first char­ acter of the IFS special variable. That is, "$*" is equivalent to "$1c$2c...", where c is the first character of the value of the IFS variable. If IFS is unset, the parameters are separated by spaces. If IFS is null, the parameters are joined without intervening separators.

@ Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is, "$@" is equivalent to "$1" "$2" ... When there are no positional parameters, "$@" and $@ expand to nothing (i.e., they are removed).

  • A_L
  • Registratie: Juni 2001
  • Niet online
RikY schreef op 02 December 2002 @ 14:55:
Gebruik "$@" ipv $*

Uit man bash:
[...]
En ik dacht dat ik de documentatie had gelezen.... 8)7
iig bedankt. Ik zal eens gaan kijken naar $@ en IFS

En er zijn inderdaad wel work-arounds.

[ Voor 3% gewijzigd door A_L op 02-12-2002 15:13 . Reden: typos ]


  • A_L
  • Registratie: Juni 2001
  • Niet online
"$@" gebruiken in plaats van $* is inderdaad het simpelste.

dit voorbeeld werkt dus wel:
code:
1
2
3
4
for archive in "$@"
do
    echo "$archive"
done