Il s’avère que iptables ne gère pas très bien les zéros non significatifs. Comme $machinenumber
doit être précédé d'un zéro initial à d'autres fins, il s'agit simplement de créer une nouvelle variable ($nozero
) basée sur $machinenumber
, où les zéros sont éliminés.
$machinenumber
est un nombre à deux chiffres compris entre 01 et 24. Il est actuellement 09
$machinetype
est 74 pour l'instant et n'a pas causé de problèmes auparavant.
Ce que j'ai jusqu'ici c'est:
nozero = (echo $machinenumber | sed 's/^0*//')
iptables -t nat -I POSTROUTING -s 10.($machinetype).($nozero).0/24 -j MASQUERADE
Bien que je pense être sur la bonne voie, le code se traduit par:
ERROR - Unknown string operation
Vous n'avez pas besoin d'utiliser sed
ou un autre utilitaire externe. Voici quelques façons dont Bash peut supprimer les zéros non significatifs pour vous.
iptables -t nat -I POSTROUTING -s "10.$machinetype.$((10#$machinenumber)).0/24" -j MASQUERADE
$(())
définit un contexte arithmétique et le 10#
convertit le nombre de base 10 en base 10, ce qui entraîne la suppression des zéros non significatifs.
shopt -s extglob
iptables -t nat -I POSTROUTING -s "10.$machinetype.${machinenumber##+(0)}.0/24" -j MASQUERADE
Lorsque extglob
est activé, le développement de paramètre présenté supprime tous les zéros non significatifs. Malheureusement, si la valeur d'origine est 0, le résultat est une chaîne nulle.
Non, vous corrigez tout (presque tous) correctement… .. Il vous suffit de:
=
$()
ou des backticks au lieu de ()
Ce serait correct:
nozero=$(echo $machinenumber | sed 's/^0*//')
Aussi, vous devez utiliser des variables sans ()
autour d'elles. Vous pouvez ajouter ""
si vous voulez:
iptables -t nat -I POSTROUTING -s "10.$machinetype.$nozero.0/24" -j MASQUERADE
Et bien sûr, les variables ici ne sont pas nécessaires. Vous pouvez dire simplement:
iptables -t nat -I POSTROUTING -s "10.$(echo $machinenumber | sed 's/^0*//').$nozero.0/24" -j MASQUERADE
tu peux aussi faire
machinenumber=$(expr $machinenumber + 0)
Je ne peux pas commenter car je n'ai pas assez de réputation, mais je suggérerais que vous acceptiez la réponse de Dennis (ce qui est vraiment très joli)
Premièrement, je ne pense pas que votre réponse soit valide bash . Dans mon installation, je reçois:
> machinetype=74
> machinenumber=05
> iptables -t nat -I POSTROUTING -s 10.($machinetype).($machinenumber + 0).0/24 -j MASQUERADE
-bash: syntax error near unexpected token `('
> echo 10.($machinetype).($machinenumber + 0).0/24
-bash: syntax error near unexpected token `('
Si je le cite je reçois:
> echo "($machinetype).($machinenumber + 0)"
(74).(05 + 0)
Je suppose que vous voulez dire:
> echo 10.$(($machinetype)).$(($machinenumber + 0)).0/24
10.74.5.0/24
Mais, bien sûr, c'est toujours une mauvaise solution à cause de l'octal:
> machinenumber=09
> echo 10.$(($machinetype)).$(($machinenumber + 0)).0/24
-bash: 09: value too great for base (error token is "09")
Je suppose que vos chiffres ne sont pas 08 ou 09 pour le moment.
Voici Dennis's:
> echo $((10#09))
9
> echo $((10#00))
0
> echo $((10#00005))
5
> echo $((10#))
0
Certes, ce dernier pourrait être un problème de validation d’entrée pour quelqu'un.
La solution sed a le problème de:
> echo "0" | sed 's/^0*//'
>
nozero=$(echo $machinenumber | sed 's/^0*//')
Essayez sans espaces autour de =
et avec un signe supplémentaire $
.
Une solution pure bash:
> N=0001023450
> [[ $N =~ "0*(.*)" ]] && N=${BASH_REMATCH[1]}
> echo $N
1023450
Utilisation de sed:
echo 000498 | sed "s/^0*\([1-9]\)/\1/;s/^0*$/0/"
498
echo 000 | sed "s/^0*\([1-9]\)/\1/;s/^0*$/0/"
0
Je le fais en utilisant
awk '{print $1 + 0}'
J'aime mieux cette approche que sed car elle fonctionne toujours avec des nombres comme 0, 000 et 001.
Donc, dans votre exemple, je remplacerais
nozero=$(echo $machinenumber | sed 's/^0*//')
avec
nozero=$(echo $machinenumber | awk '{print $1 + 0}' )
Je ne peux pas non plus commenter ou voter, mais la réponse de Duncan Irvine est la meilleure.
J'aimerais ajouter une note sur la portabilité. La syntaxe $((10#0009))
n'est pas portable. Cela fonctionne en bash et en ksh, mais pas au tiret:
$ echo $((10#09))
dash: 1: arithmetic expression: expecting EOF: "10#09"
$ dpkg -s dash | grep -i version
Version: 0.5.7-2ubuntu2
Si la portabilité est importante pour vous, utilisez la réponse sed.
Je dirais que vous êtes très proche. Je ne vois pas d'exigence spécifiée pour bash, mais votre logique non nulle est imparfaite.
nonzero=`echo $machinenumber + 0 | bc`
iptables -t nat -I POSTROUTING -s 10.$machinetype.$nozero.0/24 -j MASQUERADE
L'ajout de 0 est une méthode courante pour changer un numéro de chaîne en un entier non complété. BC est une calculatrice de base. J'utilise cette méthode pour supprimer tout le temps l'espace et les zéros.
Bien que je ne sois pas expert en syntaxe iptables, je suis presque sûr que les parenthèses ne sont pas nécessaires. Comme j'ai déjà des caractères non-Word bordant les deux variables, je n'ai pas besoin de lettres spéciales autour d'eux. Les caractères de mot sont;
[a-zA-z0-9_]
Avec cette solution, vous ne perdez pas la valeur zéro en tant que valeur potentielle et devez être portable dans tous les environnements.
Ajoutez le nombre avec 0, cela supprimera les zéros de gauche
eg: expr 00010 + 0 #becomes 10
OR
num=00076
num=${num##+(0)}
echo $num
Si vous n'avez pas sed, awk ou Perl, vous pouvez utiliser cut et grep
mn="$machinenumber"
while echo "$mn"|grep -q '^0';do mn=$(echo "$mn"|cut -c2-);done
iptables -t nat -I POSTROUTING -s 10.($machinetype).($mn).0/24 -j MASQUERADE
Fonctionne avec les deux bash et dash shell.
Si vous utilisez bash, cela ressemble au plus simple:
nozero=$(bc<<<$machinenumber)