Iptablesは先行ゼロをうまく処理していないことがわかります。使用される$machinenumber
は、他の目的のために先行ゼロを持たなければならないため、$nozero
に基づいて新しい変数($machinenumber
)を作成するだけです。離れて。
$machinenumber
は01から24までの2桁の数字です。現在は09です
$machinetype
は現在74であり、以前は問題を引き起こしていません。
私がこれまでに持っているものは:
nozero = (echo $machinenumber | sed 's/^0*//')
iptables -t nat -I POSTROUTING -s 10.($machinetype).($nozero).0/24 -j MASQUERADE
私は正しい軌道に乗っていると信じていますが、コードの結果は次のとおりです。
ERROR - Unknown string operation
関係のないものがあるため、先日このコードを再確認しなければならず、同じスクリプトを読み取る他のソフトウェアとの互換性のため、これを書き換えるのが最も簡単であることがわかりました。
iptables -t nat -I POSTROUTING -s 10.($machinetype).($machinenumber + 0).0/24 -j MASQUERADE
基本的に、0を追加すると強制的に整数として解釈されるため、先行ゼロが自動的に削除されます
sed
または別の外部ユーティリティを使用する必要はありません。 Bashが先行ゼロを取り除くことができるいくつかの方法を以下に示します。
_iptables -t nat -I POSTROUTING -s "10.$machinetype.$((10#$machinenumber)).0/24" -j MASQUERADE
_
$(())
は算術コンテキストを設定し、_10#
_は数値を基数10から基数10に変換し、先行ゼロを削除します。
_shopt -s extglob
iptables -t nat -I POSTROUTING -s "10.$machinetype.${machinenumber##+(0)}.0/24" -j MASQUERADE
_
extglob
がオンになっている場合、示されているパラメーター拡張により、先行ゼロがすべて削除されます。残念ながら、元の値が0の場合、結果はNULL文字列になります。
いいえ、すべて(ほとんどすべて)を正しくします。あなたはただする必要があります:
=
_の周りのスペースを削除します()
_の代わりに$()
またはバックティックを使用しますそれは正しいでしょう:
_ nozero=$(echo $machinenumber | sed 's/^0*//')
_
また、変数を_()
_なしで使用する必要があります。必要に応じて_""
_を追加できます。
_iptables -t nat -I POSTROUTING -s "10.$machinetype.$nozero.0/24" -j MASQUERADE
_
そしてもちろん、ここの変数は必要ありません。あなたは簡単に言うことができます:
_iptables -t nat -I POSTROUTING -s "10.$(echo $machinenumber | sed 's/^0*//').$nozero.0/24" -j MASQUERADE
_
あなたもできる
machinenumber=$(expr $machinenumber + 0)
私は十分な評判がないのでコメントすることはできませんが、受け入れることをお勧めします デニスの答え (これは非常にきれいです)
第一に、あなたの答えが有効なバッシュだとは思いません。私のインストールで私は得る:
> 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 `('
引用すると、次のようになります:
> echo "($machinetype).($machinenumber + 0)"
(74).(05 + 0)
私はあなたが意味すると仮定しています:
> echo 10.$(($machinetype)).$(($machinenumber + 0)).0/24
10.74.5.0/24
しかし、もちろん、8進数のため、それはまだ悪い解決策です。
> machinenumber=09
> echo 10.$(($machinetype)).$(($machinenumber + 0)).0/24
-bash: 09: value too great for base (error token is "09")
私はあなたの番号が現時点で08または09ではないと仮定します。
デニスは次のとおりです。
> echo $((10#09))
9
> echo $((10#00))
0
> echo $((10#00005))
5
> echo $((10#))
0
確かに、最後の問題は誰かにとっての入力検証の問題かもしれません。
Sedソリューションには次の問題があります。
> echo "0" | sed 's/^0*//'
>
nozero=$(echo $machinenumber | sed 's/^0*//')
=
の前後にスペースを入れずに、$
記号を追加してみてください。
純粋なbashソリューション:
> N=0001023450
> [[ $N =~ "0*(.*)" ]] && N=${BASH_REMATCH[1]}
> echo $N
1023450
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
私はそれを使ってそれをします
awk '{print $1 + 0}'
0、000、001などの数値でも機能するため、sedアプローチよりもこの方法の方が好きです。
だからあなたの例では私は置き換えます
nozero=$(echo $machinenumber | sed 's/^0*//')
と
nozero=$(echo $machinenumber | awk '{print $1 + 0}' )
まだコメントしたり投票したりすることもできませんが、ダンカンアーバインの答えが最高です。
移植性に関するメモを追加したいと思います。 $((10#0009))
構文は移植できません。 bashとkshで機能しますが、ダッシュでは機能しません。
$ echo $((10#09))
dash: 1: arithmetic expression: expecting EOF: "10#09"
$ dpkg -s dash | grep -i version
Version: 0.5.7-2ubuntu2
移植性が重要な場合は、sed回答を使用してください。
私はあなたが非常に近いと言います。 bashの要件は記載されていませんが、非ゼロロジックには欠陥があります。
nonzero=`echo $machinenumber + 0 | bc`
iptables -t nat -I POSTROUTING -s 10.$machinetype.$nozero.0/24 -j MASQUERADE
0を追加することは、文字列番号を非埋め込み整数に変更する一般的な方法です。 bcは基本的な計算機です。この方法を使用して、常に数字からスペースとゼロパディングを削除します。
私はiptables構文の専門家ではありませんが、括弧は必要ないと確信しています。両方の変数に接する非Word文字が既にあるので、それらの周りに特別な囲いは必要ありません。単語の文字は次のとおりです。
[a-zA-z0-9_]
このソリューションを使用すると、潜在的な値としてゼロが失われることはなく、すべてのシェルで移植可能になります。
Bashを使用している場合、これは最も単純なように見えます。
nozero=$(bc<<<$machinenumber)
0の数値を追加すると、先行ゼロが削除されます
eg: expr 00010 + 0 #becomes 10
OR
num=00076
num=${num##+(0)}
echo $num
Sed、awk、またはPerlがない場合は、cutおよび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
Bashとdashシェルの両方で動作します。