Meu dash
script recebe um parâmetro na forma de hostname:port
, ou seja:
myhost:1234
Considerando que a porta é opcional, ou seja:
myhost
Eu preciso ler o host e a porta em variáveis separadas. No primeiro caso, posso fazer:
HOST=${1%%:*}
PORT=${1##*:}
Mas isso não funciona no segundo caso, quando a porta foi omitida; echo ${1##*:}
simplesmente retorna o nome do host, em vez de uma string vazia.
No Bash, eu poderia fazer:
IFS=: read A B <<< asdf:111
Mas isso não funciona em dash
.
Posso dividir a string :
em traço, sem chamar programas externos ( awk
, tr
, etc.)?
Apenas faça:
Você pode querer alterar o
case $1
tocase ${1##*[]]}
para contabilizar valores$1
como[::1]
(um endereço IPv6 sem parte da porta ).Para dividir, você pode usar o operador split+glob (deixe uma expansão de parâmetro sem aspas), pois é para isso que serve afinal:
(embora isso não permita nomes de host que contenham dois pontos (como para o endereço IPv6 acima)).
Esse operador split+glob atrapalha e causa tantos danos no resto do tempo que seria justo que fosse usado sempre que necessário (embora eu concorde que é muito complicado de usar, especialmente considerando que o POSIX
sh
não tem suporte para escopo local, nem para variáveis ($IFS
aqui) nem para opções (noglob
aqui) (emboraash
e derivados comodash
sejam alguns dos que fazem (junto com implementações da AT&T deksh
,zsh
ebash
4.4 e acima)).Observe que
IFS=: read A B <<< "$1"
tem alguns problemas próprios:-r
que significa que a barra invertida passará por algum processamento especial.[::1]:443
em[
e em:1]:443
vez de[
e a string vazia (para a qual você precisaria deIFS=: read -r A B rest_ignored
ou[::1]
e443
(para a qual você não pode usar essa abordagem)-d ''
inzsh
oubash
e os dados não contenham caracteres NUL, mas observe que herestrings (ou heredocs) adicionam um caractere de nova linha extra!)zsh
(de onde vem a sintaxe) ebash
, aqui as strings são implementadas usando arquivos temporários, então geralmente é menos eficiente do que usar${x#y}
operadores split+glob.Basta remover o
:
em uma declaração separada; além disso, remova $host da entrada para obter a porta:Outro pensamento:
Uma string here é apenas um atalho sintático para um documento here de uma linha.