Mon dash
script prend un paramètre sous la forme de hostname:port
:
myhost:1234
Alors que le port est facultatif, c'est-à-dire:
myhost
J'ai besoin de lire l'hôte et le port dans des variables distinctes. Dans le premier cas, je peux faire:
HOST=${1%%:*}
PORT=${1##*:}
Mais cela ne fonctionne pas dans le deuxième cas, lorsque le port a été omis; echo ${1##*:}
renvoie simplement le nom d'hôte, au lieu d'une chaîne vide.
Dans Bash, je pourrais faire:
IFS=: read A B <<< asdf:111
Mais cela ne fonctionne pas dash
.
Puis - je diviser la chaîne sur :
au tableau de bord, sans faire appel à des programmes externes ( awk
, tr
, etc.)?
%%
rend gourmand (par opposition à%
), il le fait donc, au moins en partie; cela ne fonctionnerait pas avec##
.Réponses:
Faites juste:
Vous souhaiterez peut-être modifier le
case $1
pourcase ${1##*[]]}
tenir compte des valeurs de$1
similaires[::1]
(une adresse IPv6 sans partie de port ).Pour diviser, vous pouvez utiliser l' opérateur split + glob (laisser une extension de paramètre sans guillemets) car c'est à cela qu'il sert après tout:
(bien que cela n'autorise pas les noms d'hôtes contenant deux points (comme pour l'adresse IPv6 ci-dessus)).
Cet opérateur split + glob se met en travers du chemin et cause tellement de dommages le reste du temps qu'il semblerait juste qu'il soit utilisé chaque fois qu'il est nécessaire (cependant, je conviendrai que c'est très lourd à utiliser, d'autant plus que POSIX
sh
n'a pas prise en charge de la portée locale, ni pour les variables ($IFS
ici) ni pour les options (noglob
ici) (bienash
que des dérivés commedash
ceux qui le font (avec les implémentations AT&T deksh
,zsh
etbash
4.4 et ci-dessus)).Notez que cela
IFS=: read A B <<< "$1"
a quelques problèmes qui lui sont propres:-r
qui signifie que la barre oblique inverse subira un traitement spécial.[::1]:443
en[
et:1]:443
au lieu de[
et la chaîne vide (pour laquelle vous auriez besoinIFS=: read -r A B rest_ignored
ou[::1]
et443
(pour lequel vous ne pouvez pas utiliser cette approche)-d ''
danszsh
oubash
et que les données ne contiennent pas de caractères NUL, mais notez ensuite que ses chaînes (ou heredocs) ajoutent un caractère de nouvelle ligne supplémentaire!)zsh
(d'où vient la syntaxe) etbash
, ici, les chaînes sont implémentées à l'aide de fichiers temporaires, donc c'est généralement moins efficace que d'utiliser${x#y}
ou de diviser + des opérateurs glob.la source
Supprimez simplement le
:
dans une déclaration distincte; supprimez également $ host de l'entrée pour obtenir le port:la source
Une autre pensée:
la source
Une chaîne ici n'est qu'un raccourci syntaxique pour un document ici d'une seule ligne.
la source