Benzer bir POSIX işlevi yazdım, ancak bu rastgele kod yürütülmesini riske atmıyor:
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
Ayrıca, sağlamayı düşündüğünüz kadar çok argümanı da ele alacaktır. Bağımsız değişken, başka bir şekilde ayarlanmamış geçerli bir adsa, sessizce yoksayılır. Bağımsız değişken kötü bir adsa, stderr'e yazar ve uygun şekilde durur, ancak komut satırında geçersiz olandan önceki geçerli ad yine de işlenir.
Başka bir yol düşündüm. Çok daha hoşuma gitti.
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
Her ikisi de aynı teknikleri kullanıyor. Temel olarak, bir kabuk değişkeni ayarlanmamışsa, ona bir başvuru bir +
parametre genişletmesiyle genişletilmez. Ancak, değerinden bağımsız olarak ayarlanırsa , değişkenin değerine değil : gibi bir parametre genişletmesi ${parameter+word}
genişler word
. Ve böylece kabuk değişkenleri kendini test eder ve kendini yerine geçer.
Ayrıca kendi kendine başarısız olabilirler . Üst işlevde kötü bir ad bulunursa içeri $1
girer $2
ve $1
null bırakırım çünkü yaptığım bir sonraki şey ya return
tüm argümanlar işlenmişse ve döngü sonundaysa ya da arg geçersizse, kabuk genişletmek $2
içine $1:?
hangi bir metne kabuk öldürmek ve yazarken interaktif birine bir kesme dönecektir word
stderr'e.
İkincisinde getopts
ödevler yapılır. Ve kötü bir ad atamaz - bunun yerine yazma stderr'e standart bir hata mesajı yazacaktır. Dahası , argüman ilk etapta bir set değişkeninin adı $OPTARG
ise arg değerini kaydeder . Yani getopts
gereken her şeyi yaptıktan sonra eval
bir setin OPTARG
uygun atamaya genişlemesi.
mktemp
eğer o source değişkeni atamak için geçici dosya taşınabilir yeterlidir ve değersiz bırakılarak tanımsız ve. En azından geçici bir dosya, bir kabuk değişkeninin aksine az ya da çok keyfi bir adla oluşturulabilir.