Jaki jest lepszy sposób wdrożenia print_last_arg
?
#!/bin/sh
print_last_arg () {
eval "echo \${$#}" # this hurts
}
print_last_arg foo bar baz
# baz
(Gdyby tak było, powiedzmy, #!/usr/bin/zsh
zamiast #!/bin/sh
wiedzieć, co robić. Moim problemem jest znalezienie rozsądnego sposobu na wdrożenie tego #!/bin/sh
.)
EDYCJA: Powyższe to tylko głupi przykład. Moim celem nie jest wydrukowanie ostatniego argumentu, ale raczej sposób na odniesienie się do ostatniego argumentu w funkcji powłoki.
EDYCJA 2: Przepraszam za tak niejasno sformułowane pytanie. Mam nadzieję, że tym razem wszystko będzie dobrze.
Gdyby tak było /bin/zsh
, zamiast /bin/sh
, mogę napisać coś takiego
#!/bin/zsh
print_last_arg () {
local last_arg=$argv[$#]
echo $last_arg
}
Wyrażenie $argv[$#]
jest przykładem tego, co opisałem w moim pierwszym EDYCJI jako sposobu na odniesienie do ostatniego argumentu w funkcji powłoki .
Dlatego naprawdę powinienem był napisać mój oryginalny przykład w ten sposób:
print_last_arg () {
local last_arg=$(eval "echo \${$#}") # but this hurts even more
echo $last_arg
}
... aby wyjaśnić, że to, czego szukam, jest mniej okropnym posunięciem na prawo od zadania.
Należy jednak pamiętać, że we wszystkich przykładach do ostatniego argumentu można uzyskać dostęp nieniszczący . IOW, dostęp do ostatniego argumentu pozostawia argumenty pozycyjne jako całość bez zmian.
var=$( eval echo \${$#})
się eval var=\${$#}
- obaj są niczym podobni.
shift
i set -- ...
rozwiązań opartych może być destrukcyjna, chyba że wykorzystywane w funkcjach, gdzie są one nieszkodliwe też.
eval "var=\${$#}"
porównaniu var=${arr[evaled index]}
z tym, że $#
jest to gwarantowana bezpieczna wartość. po co kopiować cały zestaw, a potem go niszczyć, skoro można go po prostu bezpośrednio zindeksować?