bygge argumentlister som inneholder mellomrom

stemmer
8

I bash kan man unnslippe argumenter som inneholder mellomrom.

foo a string

Dette fungerer også for argumenter til en kommando eller funksjon:

bar() {
    foo $@
}

bar a string

Så langt så bra, men hva om jeg ønsker å manipulere argumentene før du ringer foo?

Dette fungerer ikke:

bar() {
    for arg in $@
    do
        args=$args \prefix $arg\
    done

    # Everything looks good ...
    echo $args

    # ... but it isn't.
    foo $args

    # foo $args would just be silly
}

bar a b c

Så hvordan kan du bygge argumentlister når argumentene inneholde mellomrom?

Publisert på 04/01/2009 klokken 19:04
kilden bruker
På andre språk...                            


5 svar

stemmer
2

Bruk matriser (en av de skjulte funksjoner i Bash).

Svarte 04/01/2009 kl. 19:51
kilden bruker

stemmer
14

Det er (minst) to måter å gjøre dette:

(1) Bruk en matrise og utvide den ved hjelp av "${array[@]}":

bar() {
    local i=0 args=()
    for arg in "$@"
    do
        args[$i]="prefix $arg"
        ((++i))
    done

    foo "${args[@]}"
}

Så hva har vi lært? "${array[@]}"det å ${array[*]}hva "$@"det til $*.

(2.) Eller hvis du ikke ønsker å bruke arrays du trenger å bruke eval:

bar() {
    local args=()
    for arg in "$@"
    do
        args="$args \"prefix $arg\""
    done

    eval foo $args
}
Svarte 05/01/2009 kl. 00:38
kilden bruker

stemmer
0

Du kan bruke arrays akkurat som du foreslår, med en liten detalj endret. Linjen kaller foo bør lese

 foo "${args[@]}"
Svarte 06/01/2009 kl. 14:42
kilden bruker

stemmer
0

Jeg hadde et problem med dette også i tillegg. Jeg skrev et bash script for å ta sikkerhetskopi av viktige filer på min Windows-maskin (cygwin). Jeg prøvde matrisen tilnærming også, og hadde fortsatt noen problemer. Ikke sikker på nøyaktig hvordan jeg fikset det, men her er de delene av min kode som er viktig i tilfelle vil det hjelpe deg.

WORK="d:\Work Documents\*"
#   prompt and 7zip each file
for x in $SVN $WEB1 $WEB2 "$WORK" $GRAPHICS $W_SQL
do
    echo "Add $x to archive? (y/n)"
    read DO
    if [ "$DO" == "y" ]; then
        echo "compressing $x"
        7zip a $W_OUTPUT "$x"
    fi
    echo ""
done
Svarte 06/01/2009 kl. 14:52
kilden bruker

stemmer
3

Her er en kortere versjon: (eksempel bygge argumenter til en findkommando)

dir=$(shift)
for f in "$@" ; do
    args+=(-iname "*$f*")
done
find "$dir" "${args[@]}"
Svarte 03/10/2013 kl. 19:44
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more