DASHスクリプトエラー:変数を正しく設定する方法がわからないようです。

DASHスクリプトエラー:変数を正しく設定する方法がわからないようです。
#!/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

dash0.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=0x0000001つを実行します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 $DONEtest
  • 変数を参照するとき読む、式に示されているとおりです。
  • 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に規定されている定数は定数として認識されなければなりません。

しかしテストスプリントprintfDebian 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時間かかりますが、設定して忘れてください:)

関連情報