#!/bin/sh
export $REG=0x000000
export $DONE=0x4A9FFF
while $REG -le $DONE
do
(($REG+1))
printf 'wm8280_reg get 0x'$REG'\r\n'
sleep 1
done
이로 인해 오류가 발생합니다.
./wm8280_reg_get1.sh: line 3: export: `=000000': not a valid identifier
./wm8280_reg_get1.sh: line 4: export: `=4A9FFF': not a valid identifier
./wm8280_reg_get1.sh: line 6: -le: command not found
나는 그것이 "작거나 같음"에 dash
대한 것이라고 확신 하지만 분명히 내가 틀렸습니다. -le
또한 내 변수가 왜 잘못된지 잘 모르겠습니다. 내가 뭘 잘못했나요?
답변1
sh
최신 버전을 포함하여 모든 규격 구현에서 작동해야 하는 표준(POSIX) 구문은 다음 dash
과 같습니다.
#!/bin/sh -
reg=0x000000
done=0x4A9FFF
while [ "$((reg))" -le "$((done))" ]; do
reg=$((reg + 1))
printf 'wm8280_reg get 0x%06X\r\n' "$reg"
sleep 1
done
dash
0.5.5(2009) 이전 버전 으로 마이그레이션해야 하는 경우 다음이 필요합니다.
#!/bin/sh -
reg=0x000000
done=0x4A9FFF
while [ "$(($reg))" -le "$(($done))" ]; do
reg=$(($reg + 1))
printf 'wm8280_reg get 0x%06X\r\n' "$reg"
sleep 1
done
POSIX 사양은 확장 방법(본문에서는 아직 명확하지 않지만 최소한 메일링 리스트와 적합성 테스트 제품군에서는 Open Group의 입장이 명확해졌습니다)과 기본 변수 사용에 $((reg))
대해 과거에는 그다지 명확하지 않았습니다. dash
산술 표현식은 지원되지 않지만( no $
) 사양은 "$(($ver))
항상 더 명확합니다.
$reg
첫 번째 호출 이후에는 10진수로 표시 되므로 reg=$(($reg + 1))
처음에는 변수를 10진수로 변환할 수도 있습니다. 또한 0x1 ~ 0x4AA000(56일 후)의 숫자를 인쇄한다는 점에 유의하세요. 보다 전통적인(그리고 제 생각에는 더 명확한) 작성 방법은 다음과 같습니다.
#!/bin/sh -
reg=$((0x000001)) done=$((0x4AA000))
while [ "$reg" -le "$done" ]; do
printf 'wm8280_reg get 0x%06X\r\n' "$reg"
sleep 1
reg=$(($reg + 1))
done
또한 매초마다 정확히 한 줄을 인쇄할 것으로 기대하지 마십시오. 이러한 명령을 실행하는 데 걸리는 시간으로 인해 편향이 발생합니다.
세부 사항:
export
실행하려는 명령의 환경으로 변수를 내보내면 됩니다. 여기서는 사용해도 소용이 없습니다. 이 변수는 여기서만 전달하는 데 사용됩니다.값명령의 매개변수로.$
값을 확장하려는 경우 앞에 변수를 넣을 수 있습니다.export $reg=0x000000
하나를 실행합니다export value-of-reg=0x000000
.while
그 뒤에는 실행할 명령(또는 명령 목록)이 오고 해당 종료 상태가 루프 조건을 결정합니다. 여기에는[
정수 비교와 같은 다양한 테스트를 수행하는 데 사용할 수 있는 명령(대부분의 쉘에 내장되어 있음)이 필요합니다 .- 그러나 이러한 산술 비교 연산자는
[
10진수 정수 상수만 지원하므로 이를 10진수로 변환하기 위해 쉘 산술 확장(16진수 지원)을 사용합니다. - 화장품: 관례에 따라 우리는 일반적으로 환경 변수나 전역 변수가 있어야 하는 변수에 대해 모두 대문자 변수 이름을 사용합니다.범위예를 들어, 함수를 사용하는 복잡한 스크립트에서.
답변2
이 예
#!/bin/sh
export $REG=0x000000
export $DONE=0x4A9FFF
while $REG -le $DONE
do
(($REG+1))
printf 'wm8280_reg get 0x'$REG'\r\n'
sleep 1
done
변경해야 할 사항:
- 이 두 줄은 변수 앞에 붙으면
export
안 됩니다 .$
- 표현식 주위에 및 사용
[
(또는 이전)]
$REG -le $DONE
test
- 변수를 참조할 때읽다, 표현식에 표시된 대로입니다.
printf
문자열 연결이 아닌 서식 지정 용
그래서 당신은 다음과 같은 것을 가질 것입니다
#!/bin/sh
export REG=0x000000
export DONE=0x4A9FFF
while [ "$REG" -le "$DONE" ]
do
(($REG+1))
printf 'wm8280_reg get 0x%s\r\n' "$REG"
sleep 1
done
이 줄
while [ "$REG" -le "$DONE" ]
다음과 같이 쓸 수도 있습니다.
while test "$REG" -le "$DONE"
(둘 다 합법적입니다).
dash의 매뉴얼 페이지를 빠르게 읽어보면 대시가 16진수 상수를 지원한다는 내용이 나와 있지 않습니다. 소수 값을 사용하도록 이러한 내보내기를 변경해야 할 수도 있습니다. 예를 들어,
export REG=0
export DONE=489063
%06X
그런 다음 대신 printf를 사용하여 %s
값을 16진수로 인쇄할 수 있습니다.
cuonglm의 제안을 사용하면 다음을 사용할 수 있습니다.
while [ "$((REG))" -le "$((DONE))" ]
그리고
REG=$(($((REG))+1))
POSIX 쉘을 참조2.6.4 산술 확장:
10진수 상수, 8진수 상수만16진수- ISO C 표준 6.4.4.1항에 명시된 상수는 상수로 인식되어야 합니다.
그러나 테스트스프린트printf
Debian 7 및 8에서는 16진수로 가정할 때 결과가 10진수이기 때문에 증가 표현식이 OP가 의도한 대로 작동하지 않을 수 있습니다 . 또한 REG=((REG+1))
이 대시 버전에서는 작동하지 않습니다. (물론 bash는 다른 이야기입니다).
답변3
좋아요, 여러분의 의견에 감사드립니다. 최종 스크립트는 다음과 같습니다.
#!/bin/sh
export REG=0
export DONE=4890632
while [ "$((REG))" -le "$((DONE))" ]
do
wm8280_reg get $REG >> "wm_reg_dump.txt"
REG=$(($((REG))+1))
done
DASH에서 실행되며 원하는 출력을 갖습니다. 물론 코드를 실행하는 데 8시간이 걸리지만, 설정하고 잊어버리세요 :)