![추상적인:](https://linux55.com/image/141289/%EC%B6%94%EC%83%81%EC%A0%81%EC%9D%B8%3A.png)
레몬 바 구성을 시도하고 설정하기 위해 이 가이드를 따르고 있습니다.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
awk
read
모든 '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
$IFS
awk
read t f
zsh
위와 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를 한 번만 호출하면 모든 작업이 완료됩니다.bc
cut
</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
명령으로 읽은 문자열에는 read
1개의 필드만 포함되며, 그 중 2개는 동시에 채워 t
지고 변수가 될 것으로 예상됩니다.f
| tr '\n' ' '
이 문제는 명령 뒤에 추가하여 해결할 수 있습니다 awk
.
하지만 다음과 같이 단순화하는 것이 좋습니다.
read t f <<< $(awk '/MemTotal/{t=$2}/MemFree/{f=$2}END{print t,f}' /proc/meminfo)