추상적인:

추상적인:

레몬 바 구성을 시도하고 설정하기 위해 이 가이드를 따르고 있습니다.http://blog.z3bra.org/2014/04/meeting-at-the-bar.html

이제 다음 줄을 제외하고 거의 모든 것이 완벽하게 작동합니다.

bc <<< "scale=2; 100 - $f / $t * 100" | cut -d. -f1

이 기능에서:

memused() {
    read t f <<< `grep -E 'Mem(Total|Free)' /proc/meminfo |awk '{print $2}'`
    bc <<< "scale=2; 100 - $f / $t * 100" | cut -d. -f1
}

다음 오류가 발생합니다.(standard_in) 1: syntax error

이제 제가 아는 한, 방정식 주위에 이중 괄호를 추가해야 합니다. (())그러나 다양한 배열을 시도했지만 아무것도 오류를 수정하지 못했습니다.

답변1

awkread모든 's, cut's, grep's 및 bc's는 여기서 수행할 수 있습니다 .

 awk -F': *' '
   $1 == "MemTotal" {t = $2}
   $1 == "MemFree" {f = $2}
   END {printf "%.1f%%\n", (t - f) * 100 / t}' /proc/meminfo

awk쉼표를 소수점 밑으로 사용하는 로케일에서 모든 구현이 40.5 대신 40.5%를 출력하는 것은 아닙니다 (GNU는 환경에서 awk와 같이 POSIX 모드에서만 이 작업을 수행합니다 ). 소수점 밑을 마침표/점으로 강제 변환 $POSIXLY_CORRECT하는 데 사용됩니다 .LC_ALL=C awk...

소수 부분이 전혀 필요하지 않으면 %.1f으로 변경하십시오. %.0f이것은 반올림됩니다최근의정수. %d소수 부분을 자르려면(99.999는 100%가 아닌 99%임) 다른 방법을 사용하십시오.

수정되지 않은 것으로 간주되는 이전 버전에서 작업 하게 read t f <<< `grep -E 'Mem(Total|Free)' /proc/meminfo |awk '{print $2}'`됩니다 .bash$IFS

에서는 cmd <<< `code`출력을 문자(기본적으로 개행 포함)로 분할 bash하고 명령을 표준 입력으로 입력하기 전에 첫 번째 문자(기본적으로 공백)와 연결하는 데 사용됩니다. 따라서 귀하의 경우 출력의 두 줄은 예상대로 한 줄에 두 단어로 제공됩니다. 이 놀라운 동작(bash-4.4의 원래 구현과도 다름)은 bash-4.4에서 수정되었습니다.code$IFS$IFSawkread t fzsh

위와 bash-4.4위에는 필요합니다 { read t; read f; } <<< "$(awk...)"( $(...)bash-4.3 및 이전 버전에서도 작동하도록 여기에 따옴표를 추가하고 기본값은 여전히 ​​가정됩니다 $IFS).

답변2

추상적인:

이식 가능, 한 줄 및 printf 사용:

awk '/MemTotal/{t=$2}; /MemFree/{f=$2}; END{printf("%d\n",(1-f/t)*100)}'

셸 전용(bash):

memused() { : # Print the (integer) value of % of free memory
            local ret ref a t f 
            ret='MemTotal:[ \t]*([0-9]+)';              # Regex for Total memory.
            ref='MemFree:[ \t]*([0-9]+)';               # Regex for Free  memory.
            a=$(</proc/meminfo)                         # Get meminfo in var (a).
            [[ $a =~ $ret ]] && t="${BASH_REMATCH[1]}"  # Get Total memory.
            [[ $a =~ $ref ]] && f="${BASH_REMATCH[1]}"  # Get Free  memory.
            printf '%s\n' "$(( 100 - 100*f/t )) %"      # Print integer % value.
          }

설명하다

BC가 불평하는 이유는 var만 얻기 때문입니다.

재현하려면:

$ t=150 ; f='' ; bc <<< "scale=2; 100 - $f / $t * 100"
(standard_in) 1: syntax error

이 오류를 방지하는 한 가지 방법은 기본값을 설정하는 것입니다.

$ t=150; f=''; bc <<< "scale=2; 100 - ${f:-0} / ${t:-0} * 100"
100

값이 하나만 있는 이유는 읽기가 별도의 줄에 있는 값을 가져오기 때문입니다(bash 4.4에서). 모든 bash 버전에서 작동하는 솔루션은 다음을 사용하는 것입니다 -d ''.

$ read -d '' t f <<< "`grep -E 'Mem(Total|Free)' /proc/meminfo |awk '{print $2}'`"
$ echo "total=<$t>     free=<$f>"
total=<1922764>     free=<424360>

이는 명령 확장명이 인용되어 있는지 여부(반드시 인용되어야 함)에 관계없이 작동합니다 "`grep … '`".

grep하지만 결국 전화할 이유가 없어졌습니다 awk. awk를 한 번만 호출하면 모든 작업이 완료됩니다.bccut

</proc/meminfo awk '/MemTotal/{t=$2}
                    /MemFree/ {f=$2}
                    END{
                        print( (1-f/t)*100 )
                    }
                   '

한 줄에 printf를 사용하면 다음과 같습니다.

awk '/MemTotal/{t=$2};/MemFree/{f=$2};END{printf("%d\n",(1-f/t)*100)}' </proc/meminfo

더 빠르게 실행하고 셸을 사용하려면(bash이기는 하지만):

memused() {  : # Print the (integer) value of % of free memory
             local ret ref a t f 
             ret='MemTotal:[ \t]*([0-9]+)';              # Regex for Total memory.
             ref='MemFree:[ \t]*([0-9]+)';               # Regex for Free  memory.
             a=$(</proc/meminfo)                         # Get meminfo in var (a).
             [[ $a =~ $ret ]] && t="${BASH_REMATCH[1]}"  # Get Total memory.
             [[ $a =~ $ref ]] && f="${BASH_REMATCH[1]}"  # Get Free  memory.
             printf '%s\n' "$(( 100 - 100*f/t )) %"      # Print integer % value.
   }

답변3

명령으로 읽은 문자열에는 read1개의 필드만 포함되며, 그 중 2개는 동시에 채워 t지고 변수가 될 것으로 예상됩니다.f

| tr '\n' ' '이 문제는 명령 뒤에 추가하여 해결할 수 있습니다 awk.

하지만 다음과 같이 단순화하는 것이 좋습니다.

read t f <<< $(awk '/MemTotal/{t=$2}/MemFree/{f=$2}END{print t,f}' /proc/meminfo)

관련 정보