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

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

Tif, 등의 조건과 함께 일반 수학 함수를 실행하는 대신 한두 줄의 내용을 사용하여 "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(데비안과 그 파생물에서는 그것의 일부 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% 미만으로 떨어질 때 이메일을 통해 경고를 보내려는 경우 특히 유용합니다.

  • -HScripted mode. Do not display headers, and separate fields by a single tab instead of arbitrary space.
  • -p"사람이 읽을 수 있는" 형식(예: 바이트)이 아닌 "구문 분석 가능한" 형식으로 인쇄합니다.

그런데 최신 버전의 ZFS에서는 zfszpool매뉴얼 페이지를 하위 명령, 속성, 개념 등에 대한 자체 페이지로 분리합니다. 이것이 실행 중인 경우 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

관련 정보