#!/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
また、毎秒正確に1行を印刷することを期待しないでください。これらのコマンドを実行するのにかかる時間が原因でバイアスが発生します。
詳細:
export
実行したいコマンドの環境に変数をエクスポートするだけです。ここでは使用しても役に立ちません。この変数はここでのみ渡すために使用されます。値コマンドのパラメータとして。$
値を拡張したい場合は、変数を前に置くことができます。export $reg=0x000000
1つを実行します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
変更すべき事項:
- これらの2行は変数の前に付け
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時間かかりますが、設定して忘れてください:)