사람이 읽을 수 있는 크기를 바이트 수량으로 변환하는 효율적인 방법은 무엇입니까?

사람이 읽을 수 있는 크기를 바이트 수량으로 변환하는 효율적인 방법은 무엇입니까?

일반 수학 함수를 실행하는 대신 , , 등에 T대한 조건을 실행하는 대신 한두 줄의 항목을 사용하여 "10.9T"의 ZFS 출력을 실제 바이트로 변환하고 싶습니다 . 이를 수행하는 효율적인 방법이 있습니까? ?GM

지금은 다음과 같은 것이 있습니다.

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숫자를 바이트 단위로 제공할 수 있습니다. 예를 들어 기본 zfs 서버에 3개의 풀(15T, 29T 및 416G)을 나열합니다.

첫째, -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

관련 정보