最も簡単ではありませんが、次のようなことができます:
$ IP=109.96.77.15
$ echo "$((${-+"(${IP//./"+256*("}))))"}&255))"
109
$ echo "$((${-+"(${IP//./"+256*("}))))"}>>8&255))"
96
$ echo "$((${-+"(${IP//./"+256*("}))))"}>>16&255))"
77
$ echo "$((${-+"(${IP//./"+256*("}))))"}>>24&255))"
15
(そのところはは、ksh93で動作するはず${var//pattern/replacement}オペレータがから来ている)、bash4.3以降、busyboxのsh、yash、mkshそしてzsh、もちろんかかわらでzsh、はるかに単純なアプローチがあります。古いバージョンのではbash、内部の引用符を削除する必要があります。他のほとんどのシェルで削除された内部引用符でも機能しますが、ksh93では機能しません。
これは$IP、IPv4アドレスの有効な4進数10進数表現が含まれていることを前提としています(ただし、これは0x6d.0x60.0x4d.0xf(および一部のシェルでは8進数でも)などの4進数16進数表現でも機能しますが、値は10進数で出力されます)。のコンテンツが$IP信頼できないソースからのものである場合、それはコマンドインジェクションの脆弱性に相当します。
基本的に、我々はすべてのを交換しているよう.に$IPと+256*(、私たちは評価してしまいます。
$(( (109+256*(96+256*(77+256*(15))))>> x &255 ))
したがって、IPv4アドレスのように、これらの4バイトから32ビット整数を構築しています(最終的にはバイトが逆になります)。次に>>、&ビットごとの演算子を使用して関連するバイトを抽出します。
それ以外の場合、算術パーサーは括弧の不一致について文句を言うため、${param+value}標準の演算子(ここ$-では常に設定されることが保証されています)を使用しvalueます。ここでシェルは終了見つけることができる))開口部のために$((、そしてその後、その内部の拡張は評価する算術式になります行います。
$(((${IP//./"+256*("}))))&255))代わりに、シェルは、第2および第3の治療でしょう)終値としてそこ秒))のため$((、構文エラーを報告します。
ksh93では、次のことも実行できます。
$ echo "${IP/@(*).@(*).@(*).@(*)/\2}"
96
bash、mksh、zsh は、ksh93のコピーした${var/pattern/replacement}オペレータをしかし、キャプチャー・グループは、一部を処理していないこと。zsh異なる構文でサポートします:
$ setopt extendedglob # for (#b)
$ echo ${IP/(#b)(*).(*).(*).(*)/$match[2]}'
96
bashは、正規表現一致演算子である形式のキャプチャグループ処理をサポートしていますが、ではサポートしていません${var/pattern/replacement}。
POSIXly、あなたは使うでしょう:
(IFS=.; set -o noglob; set -- $IP; printf '%s\n' "$2")
のようなnoglob値の予期せぬ事態を避けるために、サブシェルはこれらの変更の範囲をオプションとに制限します。$IP10.*.*.*$IFS
IPv IPv4アドレスは32ビット整数にすぎず、たとえば127.0.0.1は多くの(最も一般的な)テキスト表現の1つにすぎません。ループバックインターフェースの同じ典型的なIPv4アドレスは、0x7f000001または127.1(127.0 1/ 8クラスAネットワーク上のアドレスであるとここではより適切なものかもしれません)、または0177.0.1、または1の他の組み合わせとして表すこともできます。8進数、10進数、または16進数として表される4つの数値。pingたとえば、これらすべてを渡すことができ、それらがすべてlocalhostにpingすることがわかります。
or またはor で任意の一時変数(ここでは$n)を設定することの副作用を気にしない場合は、次のコマンドを使用して、これらすべての表現を32ビット整数に戻すことができます。bashksh93zsh -o octalzeroeslksh -o posix
$((n=32,(${IP//./"<<(n-=8))+("})))
次に、上記のような>>/の&組み合わせですべてのコンポーネントを抽出します。
$ IP=0x7f000001
$ echo "$((n=32,(${IP//./"<<(n-=8))+("})))"
2130706433
$ IP=127.1
$ echo "$((n=32,(${IP//./"<<(n-=8))+("})))"
2130706433
$ echo "$((n=32,((${IP//./"<<(n-=8))+("}))>>24&255))"
127
$ perl -MSocket -le 'print unpack("L>", inet_aton("127.0.0.1"))'
2130706433
mkshは、算術式に符号付き32ビット整数を使用します。$((# n=32,...))そこで、符号なし32ビット数を強制的に使用することができます(およびposix8進定数を認識するためのオプション)。
IFSのためにreadそこに:IFS=. read -a ArrIP<<<"$IP"