T
ifなどの条件で通常の数学関数を実行する代わりに、1〜2行の内容を使用して、「10.9T」のZFS出力を実際のバイトに変換したいと思います。これを行う効率的な方法はありますかG
?M
今、次のようなものがあります。
MINFREE="50G"
POOLSIZE=`zpool list $POOLNAME -o size` #Size 10.9T
POOLSIZE=$(echo "$POOLSIZE" | grep -e [[:digit:))] #10.9T
POOLFREE=500M #as an example
let p=POOLSIZE x=POOLFREE y=MINFREE z=POOLSIZE;
CALC=$(expr "echo $((x / y))")
if [ "${CALC}" < 1 ]; then
# we are less than our min free space
echo alert
fi
エラーが発生します。数値ではないため、 で10.9T
式を実行できません。50G
既知の機能がありますかbash
?
MINFREE
また、上のvarで行ったようにこれを指定する便利さも気に入っています。だから、簡単な変換方法があれば良いようです。
これこれは私が避けたかったものです(各文字の大文字と小文字の区別)。しかし、スクリプトはきれいに見えます。
編集する:すべてのコメントありがとうございます!これが私の現在のコードです。 、少なくとも関連部分。
POOLNAME=san
INFORMAT=auto
#tip; specify in Gi, Ti, etc.. (optional)
MINFREE=500Gi
OUTFORMAT=iec
NOW=`date`;
LOGPATH=/var/log/zfs/zcheck.log
BOLD=$(tput bold)
BRED=${txtbld}$(tput setaf 1)
BGREEN=${txtbld}$(tput setaf 2)
BYELLOW=${txtbld}$(tput setaf 3)
TXTRESET=$(tput sgr0);
# ZFS Freespace check
#poolsize, how large is it
POOLSIZE=$(zpool list $POOLNAME -o size -p)
POOLSIZE=$(echo "$POOLSIZE" | grep -e [[:digit:]])
POOLSIZE=$(numfmt --from=iec $POOLSIZE)
#echo poolsize $POOLSIZE
#poolfree, how much free space left
POOLFREE=`zpool list $POOLNAME -o free`
#POOLFREE=$(echo "$POOLFREE" | grep -e [[:digit:]]*.[[:digit:]].)
POOLFREE=$(echo "$POOLFREE" | grep -e [[:digit:]])
POOLFREE=$(numfmt --from=$INFORMAT $POOLFREE)
#echo poolfree $POOLFREE
#grep -e "vault..[[:digit:]]*.[[:digit:]].")
#minfree, how low can we go, before alerting
MINFREE=$(numfmt --from=iec-i $MINFREE)
#echo minfree $MINFREE
#FORMATTED DATA USED FOR DISPLAYING THINGS
#echo formattiing sizes:
F_POOLSIZE=$(numfmt --from=$INFORMAT --to=$OUTFORMAT $POOLSIZE)
F_POOLFREE=$(numfmt --from=$INFORMAT --to=$OUTFORMAT $POOLFREE)
F_MINFREE=$(numfmt --from=$INFORMAT --to=$OUTFORMAT $MINFREE)
F_MINFREE=$(numfmt --from=$INFORMAT --to=$OUTFORMAT $MINFREE)
#echo
printf "${BGREEN}$F_POOLSIZE - current pool size"
printf "\n$F_MINFREE - mininium freespace allowed/as specified"
# OPERATE/CALCULATE SPACE TEST
#echo ... calculating specs, please wait..
#let f=$POOLFREE m=$MINFREE x=m/f;
declare -i x=$POOLFREE/$MINFREE;
# will be 0 if has reached low threshold, if poolfree/minfree
#echo $x
#IF_CALC=$(numfmt --to=iec-i $CALC)
if ! [ "${x}" == 1 ]; then
#printf "\n${BRED}ALERT! POOL FREESPACE is low! ($F_POOLFREE)"
printf "\n${BRED}$F_POOLFREE ${BYELLOW}- current freespace! ${BRED}(ALERT!}${BYELLOW} Is below your preset threshold!";
echo
else
printf "\nPOOLFREE - ${BGREEN}$F_POOLFREE${TXTRESET}- current freespace";
#sleep 3
fi
答え1
zfs
人間が読める数字を実際のバイトに変換する良い方法はありません。人が読むことができる数字は丸められ、正確ではありません。
正確な数値が必要な場合は、-p
オプション(マシン解析可能)を使用して出力をバイト単位にし、必要に応じて解析してフォーマットすることができます。
$ zfs list tank/var; zfs list -p tank/var
NAME USED AVAIL REFER MOUNTPOINT
tank/var 8.33G 387G 6.90G /var
NAME USED AVAIL REFER MOUNTPOINT
tank/var 8948584448 415137447936 7407120384 /var
ただし、zfs
人間が読める出力を解析して「正確な」数値に変換することは不可能です。人間が読める数字は有効数字3桁までしか指定されないため、「正確な」見積もりも有効数字3桁まで正確です。
TiB=$((2**40))
GiB=$((2**30))
# MINFREE=$((50*$TiB)) # 50 TiB
MINFREE=$((50*$GiB)) # 50 GiB
POOLFREE=$(zpool list -Hpo free "$POOLNAME") #Free in bytes
if [ "$POOLFREE" -lt "$MINFREE" ]; then
printf "alert\n"
else
printf "no alert -- %d bytes free >= %d byte minimum\n" "$POOLFREE" "$MINFREE"
fi
答え2
あなたはそれを使用することができますnumfmt
(Debianとその派生物ではそれの一部coreutils
なので、すでにそこにあるはずです):
numfmt - 数値を人間が読める文字列に変換
$ numfmt --from=iec-i 50.1Gi
53794465383
また、stdinから値を読み取ることもできます。
$ echo "50.1Gi" | numfmt --from=iec-i
53794465383
小数点区切り記号のロケール設定を検討します。
答え3
zpool list
バイト単位の数字を指定できます。たとえば、3つのプール(15T、29T、および416G)がデフォルトのzfsサーバーにリストされています。
-H
まず、とはありません-p
。
$ zpool list -o name,size,alloc,free,capacity
NAME SIZE ALLOC FREE CAP
backup 14.5T 6.15T 8.40T 42%
export 29T 17.8T 11.2T 61%
ganesh 416G 169G 247G 40%
また-H
、-p
$ zpool list -H -p -o name,size,alloc,free,capacity
backup 15994458210304 6763872280576 9230585929728 42
export 31885837205504 19592775573504 12293061632000 61
ganesh 446676598784 181604904960 265071693824 40
出力はタブで区切られているので、必要に応じてawk
処理が簡単です。cut
〜にこだわる)。このcapacity
フィールドは使用された割合であるため、プールの可用性が10%または20%未満に低下したときに電子メールで警告を送信したい場合に特に便利です。
-H
はいScripted mode. Do not display headers, and separate fields by a single tab instead of arbitrary space.
-p
「人が読める」形式(バイトなど)ではなく、「構文解析可能な」形式で印刷します。
ところで、最新バージョンのZFSでは、zfs
マニュアルzpool
ページをサブコマンド、属性、概念などの独自のページに分割します。これが実行されている場合は、zpool-list
詳細zpoolprops
についてはマニュアルページを参照してください。そうでなければちょうどman zpool
。
答え4
タグとフレーズがついていて、bash
ただ楽しんで投げてみました。
確認がありません。 (つまり、ユニットが存在する場合など)
SI基本数量1000(10^3):
#!/bin/bash
declare -A s=([Y]=24 [Z]=21 [E]=18 [P]=15 [T]=12 [G]=9 [M]=6 [K]=3)
input="$1"
suffix="${input: -1}"
number="${input:0: -1}"
printf "%.0f bytes\n" "${number}e+${s[$suffix]}"
$ ./bashsize10 1.6T
1600000000000 bytes
$ ./bashsize10 3681.914Y
3681914000000000000130023424 bytes
IEC基本数量1024(2^10)(小数点2桁を使用)
最大81.914P(64ビット)(小数点3桁などを使用する場合8.191)
#!/bin/bash
declare -A s=([P]=50 [T]=40 [G]=30 [M]=20 [K]=10)
input="$1"
suffix="${input: -1}"
number="${input:0: -1}"
d=$(printf "%.0f" "${number}e+2")
printf "%d bytes\n" "$(( d * 2 ** s["$suffix"] / 100 ))"
$ ./bashsize2 1.6T
1759218604441 bytes