일:
stdout은 로드 평균을 위에서부터 소수점 형식으로 출력합니다(예: 0.23).
세부 사항:
이 스크립트를 Chef의 검사로 구문 분석하고 그 결과가 어떤 것보다 크거나 작은지 확인해야 합니다. 예를 들면 다음과 같습니다.
describe command("top -b -n 1 | awk '/load average/ { sub(/,/,\".\",$10); printf \"%f\n\",$10}'") do
its("stdout") { should eq 0.00 }
end
이 예에서는 ""를 반환합니다.
그런데 지금 생각해보면 안에 있는 파일들과 비교가 되더라구요./proc/loadavg
진전
다음 리소스를 사용하세요.평균 부하를 얻으려면 top을 사용하세요.
이 명령을 사용하면 출력이 잘 표현되지만 출력은 문자열이므로 계산할 수 없습니다.
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ { printf "%s\n", $10}'
0,63,
하지만 printf를 소수/부동 소수점으로 변경하려고 하면 오류가 발생합니다.
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ { printf "%f\n", $10}'
0.000000
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ { printf "%d\n", $10}'
0
소리가 들리지 않습니다. 잘라내어 보세요.나쁜 생각-- 작동 안함:
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ { printf "%s\n", $10}'|cut -c1-4
0,15
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ { printf "%s\n", $10}'|$((cut -c1-4))
-4: command not found
또 다른 시도:
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ BEGIN { printf "%.f\n", $10};'
awk: line 1: syntax error at or near BEGIN
질문:
문자열 값을 십진수/부동 소수점/정수로 변환하는 방법은 무엇입니까?
ps -o user,rss
산출:
[vagrant@localhost ~]$ ps -o user,rss
USER RSS
vagrant 736
vagrant 1080
답변1
~에서gawk: 쉼표 구분 기호로 형식화된 부동 소수점 숫자 합계:
대답은 --use-lc-numeric
gawk 옵션을 사용하는 것입니다.
--use -lc-번호
이는 gawk가 입력 데이터를 구문 분석할 때 로케일의 10진수 문자를 사용하도록 강제합니다. POSIX 표준에서는 이 동작을 요구하고 gawk는 --posix가 적용될 때 그렇게 하지만 기본값은 마침표가 소수점이 아닌 로케일에서도 레거시 동작을 따르고 마침표를 소수점으로 사용하는 것입니다. 성격. 이 옵션은 --posix 옵션의 전체 엄격함 없이 기본 동작을 재정의합니다.
귀하의 경우 다음 명령이 작동합니다.
top -b -n 1 | awk --use-lc-numeric '/load average/ { printf "%f\n", $10}'
답변2
,
소수 구분 기호가 있는 로케일을 사용 중일 수 있습니다. 다음 방법 중 하나를 시도해 볼 수 있습니다.
C 로캘 사용
top
:LC_ALL=C top -b -n 1 | awk '/load average/ { printf "%f\n",$10}'
이는 마침표 대 쉼표 문제를 해결할 뿐만 아니라
load average
사용자 언어로의 번역과 같은 텍스트 문제도 방지합니다.쉼표를 점으로 바꾸십시오.
top -b -n 1 | awk '/load average/ { sub(/,/,".",$10); printf "%f\n",$10}'
GNU의 경우 플래그를
awk
사용하십시오.--use-lc-numeric
@Leo의 추천또는 를 사용하십시오POSIXLY_CORRECT=1 awk
.awk
또는 다음과 같은 POSIX 호환 구현을 사용하십시오.진짜 어이없네 기본적으로 로캘 규칙에 따라 숫자를 구문 분석하고 인쇄해야 합니다.
로드 평균을 얻는 보다 이식성 있는 명령은 입니다 uptime
.
답변3
일:
sdout 위에서부터 소수점 형식의 로드 평균(예: 0.23)
해결책:
top -b -n 1 | perl -lane 'print "$1.$2" if /load average: (\d+)[,.](\d+)/'
노트:
그러면 1m 로드 평균이 검색됩니다. 이것이 당신이 원하는 것처럼 보일 수도 있지만, 분명히 해야 합니다. 필요한 경우 코드를 쉽게 수정하여 5분, 15분 또는 3분 모두에 대한 평균 로드를 검색할 수 있습니다.
지적한대로@테덴, uptime
이 예보다 더 나은 출발점이 될 수 있습니다.top
처음 두 줄 이후에는암묵적으로결과로 무엇을 하고 싶은지 설명하세요. 당신이 취하고 싶은 다음 단계는 새로운 질문의 주제가 되어야 합니다.
Perl에서는 숫자가 자동으로 문자열로 변환되고 그 반대도 마찬가지입니다. 숫자를 나타내는 문자열에 대해 숫자 연산을 수행할 수 있습니다. 예를 들어print "$1.$2"+11.11
질문 2:
이 부분은 두 번째 질문에 관한 것입니다.전혀 관련이 없는첫 번째로.
OP에게 이 질문을 별도로 게시할 것을 촉구합니다..
문자열 값을 십진수/부동 소수점/정수로 변환하는 방법은 무엇입니까?
더 나은 작성 방법은 문자열에 대해 수치 비교를 수행하는 것입니다.요리사~의사양 확인.
해결책:
to_i
문자열을 숫자 형식으로 사용하거나 변환합니다 to_f
.
예:
describe command("echo 1.00") do
its("stdout.to_f") { should be < 1.03 }
end
설명하다:
stdout이 문자열로 처리된다는 것은 완벽하게 이해됩니다. 그것도 아주 합리적으로,숫자비교하려면 두 숫자가...숫자여야 합니다. 다행스럽게도 편리한 Ruby 문자열 메서드인 to_i
, to_f
및 를 사용하여 변환을 수행할 수 있습니다 .to_r
to_c
답변4
문제는 추출된 필드가 소수 구분 기호로 쉼표를 사용하는 반면 awk는 부동 소수점 숫자가 포인트를 사용할 것으로 예상한다는 것입니다.
이것은 문제를 재현합니다.
$ LC_ALL=de_DE top -bn 1 | awk 'NR==1'
top - 08:37:07 up 1 day, 10:22, 5 users, load average: 0,17, 0,24, 0,26
보시다시피 숫자는 쉼표를 소수 구분 기호로 사용합니다. 다음과 같은 것이 필요합니다.
$ LC_ALL=en_US top -bn 1 | awk 'NR==1'
top - 08:38:28 up 1 day, 10:23, 5 users, load average: 0.56, 0.34, 0.30
locale -a
그러나 이는 시스템에 설치된 로케일 에 따라 다릅니다 (확인). 로캘 C
설정은 항상 사용할 수 있습니다.
$ LC_ALL=C top -bn 1 | awk 'NR==1'
top - 08:40:35 up 1 day, 10:25, 5 users, load average: 0.50, 0.39, 0.31
그러나 첫 번째 행만 추출하기 위해 top을 사용하는 것은 약간 과잉입니다. 가동 시간 활용도 향상:
$ LC_ALL=C uptime
08:42:08 up 1 day, 10:27, 5 users, load average: 0.35, 0.37, 0.31
하지만 더 나은 방법은 /proc/loadavg
파일을 읽는 것입니다.
$ cat /proc/loadavg
0.29 0.34 0.30 1/468 15084
그건 그렇고, 이것은 로케일과 무관합니다. 첫 번째 숫자는 1분 로드 평균입니다. 이를 선택하고 원하는 형식으로 인쇄하세요.
$ awk '{printf( "%s\n %f\n %d\n", $1, $1, $1 )}' /proc/loadavg
0.35
0.350000
0
1, 5, 15분 로드 평균 사용량의 경우:
$ awk '{printf( "%7.3f %7.3f %5.2f\n", $1, $2, $3 )}' /proc/loadavg
0.150 0.340 0.33