Mój dash
skrypt przyjmuje parametr w postaci hostname:port
np .:
myhost:1234
Natomiast port jest opcjonalny, tj .:
myhost
Muszę odczytać hosta i port w osobne zmienne. W pierwszym przypadku mogę wykonać:
HOST=${1%%:*}
PORT=${1##*:}
Ale to nie działa w drugim przypadku, gdy port został pominięty; echo ${1##*:}
po prostu zwraca nazwę hosta zamiast pustego ciągu.
W Bash mogłem:
IFS=: read A B <<< asdf:111
Ale to nie działa dash
.
Mogę podzielić na ciąg :
w desce rozdzielczej, bez odwoływania się do zewnętrznych programów ( awk
, tr
, itd.)?
%%
sprawia, że jest chciwy (w przeciwieństwie do%
), więc faktycznie robi to, przynajmniej częściowo; to nie zadziała##
.Odpowiedzi:
Po prostu zrób:
Możesz zmienić wartość
case $1
na,case ${1##*[]]}
aby uwzględnić wartości$1
podobne[::1]
(adres IPv6 bez części portu ).Aby podzielić, możesz użyć operatora split + glob (pozostaw rozszerzenie cudzysłowu bez cudzysłowu), ponieważ po to jest to:
(choć nie pozwoli to na nazwy hostów zawierające dwukropek (jak dla powyższego adresu IPv6).
Ten operator split + glob przeszkadza i powoduje tyle szkody przez resztę czasu, że wydawałoby się sprawiedliwe, że można go używać zawsze, gdy jest to potrzebne (choć zgodzę się, że korzystanie z niego jest bardzo kłopotliwe, zwłaszcza biorąc pod uwagę, że POSIX
sh
nie ma wsparcie dla zakresu lokalnego, ani dla zmiennych ($IFS
tutaj), ani dla opcji (noglob
tutaj) (choćash
i pochodne jakdash
to tylko niektóre z tych, które wykonują (wraz z wdrożeń AT & T oksh
,zsh
ibash
4.4 i wyżej)).Pamiętaj, że
IFS=: read A B <<< "$1"
ma kilka własnych problemów:-r
co oznacza, że ukośnik zostanie poddany specjalnej obróbce.[::1]:443
się na pusty łańcuch[
i:1]:443
zamiast[
niego (do czego potrzebujeszIFS=: read -r A B rest_ignored
lub[::1]
i443
(dla którego nie możesz użyć tego podejścia)-d ''
wzsh
lubbash
dane nie zawierają znaków NUL, ale zwróć uwagę, że tutaj (lub heredoki) dodajemy dodatkowy znak nowej linii!)zsh
(skąd pochodzi składnia), abash
tutaj łańcuchy są implementowane przy użyciu plików tymczasowych, więc jest ogólnie mniej wydajne niż używanie${x#y}
lub dzielenie operatorów + glob.źródło
Po prostu usuń
:
w osobnej instrukcji; również usuń $ host z wejścia, aby uzyskać port:źródło
Kolejna myśl:
źródło
Ciąg tutaj jest tylko składniowym skrótem do jednowierszowego dokumentu tutaj.
źródło