Powiedzmy, że mam skrypt wykonujący:
some-command "$var1" "$var2" ...
A w przypadku var1
pustego wolałbym, aby zamiast pustego łańcucha zastąpić go niczym, aby polecenie zostało wykonane:
some-command "$var2" ...
i nie:
some-command '' "$var2" ...
Czy istnieje prostszy sposób niż testowanie zmiennej i warunkowe włączenie jej?
if [ -n "$1" ]; then
some-command "$var1" "$var2" ...
# or some variant using arrays to build the command
# args+=("$var1")
else
some-command "$var2" ...
fi
Czy istnieje podstawienie parametru, które nie może rozwinąć się w nic w bash, zsh itp.? Nadal mógłbym chcieć użyć globowania w pozostałych argumentach, więc wyłączenie tego i cofnięcie cytowania zmiennej nie jest opcją.
bash
shell-script
zsh
variable
muru
źródło
źródło
man
strony? (-;Odpowiedzi:
Pociski i Bash zgodne z Posix
${parameter:+word}
:Możesz więc po prostu zrobić:
i zostały
var1
sprawdzone i"$var1"
użyte, jeśli jest ustawione i niepuste (ze zwykłymi regułami podwójnego cytowania). W przeciwnym razie rozwija się do zera. Zauważ, że cytowana jest tylko część wewnętrzna , a nie całość.To samo działa również w Zsh. Musisz powtórzyć zmienną, więc nie jest idealna, ale działa dokładnie tak, jak chcesz.
Jeśli chcesz, aby zmienna set-but-empty rozwijała się do pustego argumentu, użyj
${var1+"$var1"}
zamiast tego.źródło
word
część.:+
i+
.sh
/dash
dla potencjalnych skryptów chokepoint, więc zawsze doceniam to, gdy ktoś pokazuje, jak coś jest możliwe bez uciekania się do Basha.Tak
zsh
dzieje się domyślnie po pominięciu cytatów:W rzeczywistości jedynym powodem, dla którego nadal potrzebujesz cudzysłowów w rozszerzeniu parametru zsh, jest uniknięcie takiego zachowania (puste usuwanie), ponieważ
zsh
nie ma innych problemów, które wpływają na inne powłoki, gdy nie podajesz rozszerzeń parametrów (domyślny podział + glob) .Możesz zrobić to samo z innymi powłokami podobnymi do POSIX, jeśli wyłączysz split i glob:
Teraz twierdzę, że jeśli twoja zmienna może mieć wartość 0 lub 1, powinna być tablicą, a nie zmienną skalarną i użyj:
I użyj
var1=(value)
kiedyvar1
ma zawierać jedną wartość,var1=('')
kiedy ma zawierać jedną pustą wartość, avar1=()
kiedy nie zawiera żadnej wartości.źródło
Natknąłem się na to przy użyciu rsync w skrypcie bash, który uruchomił polecenie z lub bez
-n
przełączania suchych przebiegów. Okazuje się, że rsync i wiele poleceń GNU traktują''
jako ważny pierwszy argument i działają inaczej niż gdyby go nie było.Debugowanie zajęło trochę czasu, ponieważ parametry zerowe są prawie całkowicie niewidoczne.
Ktoś z listy rsync pokazał mi sposób na uniknięcie tego problemu, jednocześnie znacznie upraszczając moje kodowanie. Jeśli dobrze to rozumiem, jest to wariant ostatniej sugestii @ Stéphane Chazelas.
Zbuduj argumenty poleceń w kilku osobnych zmiennych. Można je ustawić w dowolnej kolejności lub logice odpowiadającej problemowi.
Następnie, na końcu, użyj zmiennych, aby zbudować tablicę ze wszystkim na swoim właściwym miejscu i użyj tego jako argumentu do rzeczywistego polecenia.
W ten sposób polecenie jest wydawane tylko w jednym miejscu w kodzie zamiast powtarzane dla każdej odmiany argumentów.
Każda zmienna, która jest pusta, po prostu znika przy użyciu tej metody.
Wiem, że używanie eval jest bardzo niezadowolone. Nie pamiętam wszystkich szczegółów, ale wydawało mi się, że potrzebuję tego, aby wszystko działało w ten sposób - coś wspólnego z obsługą parametrów z osadzoną białą przestrzenią.
Przykład:
źródło