Ho scritto una funzione POSIX simile, ma ciò non rischia l'esecuzione arbitraria di codice:
unexport()
while case ${1##[0-9]*} in ### rule out leading numerics
(*[!_[:alnum:]]*|"") ### filter out bad|empty names
set "" ${1+"bad name: '$1'"} ### prep bad name error
return ${2+${1:?"$2"}} ### fail w/ above err or return
esac
do eval set '"$'"{$1+$1}"'" "$'"$1"'" "$'@\" ### $1 = ( $1+ ? $1 : "" )
eval "${1:+unset $1;$1=\$2;} shift 3" ### $$1 = ( $1:+ ? $2 : -- )
done
Gestirà anche tutti gli argomenti che ti interessano per fornirlo. Se un argomento è un nome valido che altrimenti non è già impostato, viene silenziosamente ignorato. Se un argomento è un nome errato, scrive su stderr e si interrompe in modo appropriato, anche se qualsiasi nome valido che precede un non valido sulla sua riga di comando verrà comunque elaborato.
Ho pensato ad un altro modo. Mi piace molto meglio
unexport()
while unset OPTARG; OPTIND=1 ### always work w/ $1
case ${1##[0-9]*} in ### same old same old
(*[!_[:alnum:]]*|"") ### goodname && $# > 0 || break
${1+"getopts"} : "$1" ### $# ? getopts : ":"
return ### getopts errored or ":" didnt
esac
do eval getopts :s: '"$1" -"${'"$1+s}-\$$1\""
eval unset "$1; ${OPTARG+$1=\${OPTARG}#-}"
shift
done
Bene, entrambi usano molte delle stesse tecniche. Fondamentalmente se una shell var non è impostata, un riferimento ad essa non si espanderà con l'espansione di un +parametro. Ma se è impostato - indipendentemente dal suo valore - un parametro di espansione come: ${parameter+word}si espanderà a word- e non al valore della variabile. E così le variabili di shell si auto-testano e si auto-sostituiscono in caso di successo.
Possono anche fallire da soli . Nella funzione superiore se un brutto nome viene trovato mi muovo $1in $2e congedo $1nulla perché la prossima cosa che faccio è sia returnsuccesso, se tutti i args sono stati elaborati e il ciclo è giunto al termine, oppure, se l'arg non era valido, la shell espandere il $2in $1:?cui ucciderà una shell con script e restituirà un interrupt a uno interattivo mentre si scrive wordsu stderr.
Nel secondo getoptsfa gli incarichi. E non assegnerà un brutto nome - piuttosto scriverà scriverà un messaggio di errore standard a stderr. Inoltre, salva il valore di arg $OPTARG se l'argomento era il nome di una variabile set in primo luogo. Quindi, dopo aver fatto getoptstutto ciò che è necessario, è l' espansione di evalun set OPTARGnell'assegnazione appropriata.
mktempse che è abbastanza portatile e disinserire il valore e fonte il file temporaneo per assegnare alla variabile. Almeno un file temporaneo può essere creato con un nome più o meno arbitrario in contrasto con una variabile di shell.