Mi dash
script toma un parámetro en forma de hostname:port
, es decir:
myhost:1234
Mientras que el puerto es opcional, es decir:
myhost
Necesito leer el host y el puerto en variables separadas. En el primer caso, puedo hacer:
HOST=${1%%:*}
PORT=${1##*:}
Pero eso no funciona en el segundo caso, cuando se omitió el puerto; echo ${1##*:}
simplemente devuelve el nombre de host, en lugar de una cadena vacía.
En Bash, podría hacer:
IFS=: read A B <<< asdf:111
Pero eso no funciona dash
.
¿Puedo dividir la cadena en :
en el tablero, sin invocar programas externos ( awk
, tr
, etc.)?
%%
hace codicioso (en oposición a%
), por lo que en realidad hace esto, al menos en parte; que no funcionaría con##
.Respuestas:
Solo haz:
Es posible que desee cambiar
case $1
acase ${1##*[]]}
para tener en cuenta valores$1
similares[::1]
(una dirección IPv6 sin parte de puerto ).Para dividir, puede usar el operador split + glob (deje una expansión de parámetro sin comillas) ya que para eso es:
(aunque eso no permitirá nombres de host que contengan dos puntos (como para la dirección IPv6 anterior)).
Ese operador split + glob se interpone en el camino y causa tanto daño el resto del tiempo que parecería justo que se use cuando sea necesario (aunque, estoy de acuerdo en que es muy engorroso de usar, especialmente teniendo en cuenta que POSIX
sh
no tiene soporte para el alcance local, ni para las variables ($IFS
aquí) ni para las opciones (noglob
aquí) (aunqueash
y los derivados comodash
son algunos de los que sí lo hacen (junto con las implementaciones de AT&Tksh
,zsh
ybash
4.4 y superiores)).Tenga en cuenta que
IFS=: read A B <<< "$1"
tiene algunos problemas propios:-r
que significa que la barra invertida se someterá a un procesamiento especial.[::1]:443
en[
y en:1]:443
lugar de[
y la cadena vacía (para la que necesitaríasIFS=: read -r A B rest_ignored
o[::1]
y443
(para la que no puedes usar ese enfoque)-d ''
enzsh
obash
y los datos no contiene caracteres NUL, pero tenga en cuenta que herestrings (o heredocs) no añadir una personaje de nueva línea extra!)zsh
(de donde proviene la sintaxis) ybash
, aquí, las cadenas se implementan usando archivos temporales, por lo que generalmente es menos eficiente que usar${x#y}
operadores de división o glob +.fuente
Simplemente elimine el
:
en una declaración separada; Además, elimine $ host de la entrada para obtener el puerto:fuente
Otro pensamiento:
fuente
Una cadena here es solo un atajo sintáctico para un documento here de una sola línea.
fuente