Czy podczas uruchamiania skryptu powłoki można przekazać określone parametry pozycyjne bez konieczności wprowadzania ich wszystkich po kolei?


13

Na przykład, jeśli mam skrypt ./foo, który pobiera 10 parametrów, a chcę przekazać tylko 8 parametr. Jedyny sposób, w jaki wiem, jak to zrobić obecnie, to:

./foo '' '' '' '' '' '' '' 'bar'

Czy istnieje łatwiejszy / lepszy sposób?


1
Dlatego programy zwykle używają opcji, a nie parametrów pozycyjnych, jeśli masz wiele parametrów.
Barmar

Odpowiedzi:


4

Innym sposobem na zrobienie tego jest nazwanie parametru, który chcesz zadeklarować, a następnie:

{   cat >./foo 
    chmod +x ./foo
    eight=declared ./foo
    eight=declared_and_preferred \
        ./foo 1 2 3 4 5 6 7 8
    ./foo 1 2 3 4 5 6 7 8
    ./foo
} <<\SCRIPT
#!/usr/bin/sh
: ${eight:=${8:-some_default}}
printf '$eight = %s\n' "$eight"
#END
SCRIPT

WYNIK

$eight = declared
$eight = declared_and_preferred
$eight = 8
$eight = some_default

W powyższym przykładzie jawnie zadeklarowana zmienna środowiskowa jest lepsza niż argument wiersza poleceń, ale argument wiersza poleceń jest używany, gdy zmienna środowiskowa jest pusta lub nie jest ustawiona. Gdy zarówno 8. pozycja, jak i zmienna środowiskowa $eightsą puste lub nieuzbrojone, zostaje przypisana wartość domyślna some_default$eight . W obu przypadkach :można usunąć z instrukcji :-lub :=, jeśli puste powinno być dopuszczalną wartością.

Zmienną $eightrównie dobrze można ustawić w następujący sposób:

printf '$eight = %s\n' "${eight:=${8:-some_default}}"

... a poprzedni wiersz został całkowicie pominięty, ale chciałem wykazać, że zadeklarowanie zmiennej w ten sposób skutkuje trwałą wartością, więc zrobiłem to w dwóch poleceniach. W obu przypadkach $eightustawiana jest końcowa wartość rozszerzenia tego parametru złożonego.

getopts- w przypadku niezawodnych skryptów - często jest najlepszym sposobem obsługi opcji poleceń . Z drugiej strony parametry pozycyjne są prawie zawsze najprostszym sposobem niezawodnej obsługi operandów w skrypcie.

Na przykład:

touch file$(seq -ws\ file 100)
./foo *

WYNIK

$eight = file008

Widzimy tylko ósmy operand, ale jest ich 101 globowanych z mojego katalogu testowego.


18

Zakładając, że możesz zmienić skrypt, powinieneś rozważyć użycie opcjonalnych parametrów (opcji) zamiast wymaganych parametrów (argumentów).

Jeśli masz każdy z pierwszych 7 siedmiu parametrów jako opcje i masz domyślnie pusty ciąg znaków, możesz po prostu zrobić:

./foo bar

Jeśli używasz powłoki kompatybilnej z POSIX , możesz użyć getoptsnarzędzia lub programu getopt. bash- jak większość muszli - oferuje getoptsjako wbudowane. Tak czy inaczej jest łatwiejsze niż tworzenie własnego parsera wiersza poleceń.

O ile nie zaimplementujesz czegoś takiego jak ostatnie X argumentów nie będących opcjami, to wartości ostatnich argumentów Y i argumentów opcji XY, musisz podać ciągi opcji przed każdym z 7 (teraz pustych) ciągów, jeśli chcesz ustawić którykolwiek z nich. Nie jest to jednak powszechna praktyka, zwykle opcja jest zawsze opcją, a argument argumentem, a kolejność opcji „wstawiania” jest dowolna.


5
+1dla getopt(s). Parametry pozycyjne to smutny czas i należy go unikać.
HalosGhost
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.