「バニラ」ボーンシェルの問題は、そのようなものがないことです。動作は特定の実装によって異なります。最新のほとんどの/bin/sh
es には POSIX 機能がありますが、詳細が異なります。私は、「sh-compatibility」モードに入ると、非常に古い Bourne 機能に戻る習慣があります。これは、30 年前には役に立ちましたが、組み込みシステムであっても、最新のシステムでは通常やり過ぎです。:)
とにかく、これは非常に古いシェルでも機能する一般的なカウントダウン ループですが、最新の bash/dash/ksh/zsh/etc でも問題なく機能します。コマンドが必要ですがexpr
、これはかなり安全な要件です。
i=10
while [ $i -gt 0 ]; do
...
i=`expr $i - 1`
done
したがって、組み込みシステムに がある場合printf
、スクリプトは次のとおりです。同じ「引数が指定されていない場合はデフォルトで 10 になります」動作:
#!/bin/sh
n=$1
i=${n-10}
while [ $i -gt 0 ]; do
printf '\r%s ' "$i"
i=`expr $i - 1`
sleep 1
done
(最初の 2 行はおそらく単に に置き換えることができますi=${1-10}
が、いくつかの - これも古代の - シェルは、数値パラメーターに特別なパラメーター展開を適用することを好みませんでした。)
システムに がない場合、printf
問題が発生します。シェルのビルトインのみecho
(またはビルトインなしでランダムに選択された の実装/bin/echo
)では、これらのいずれかを行う保証された方法はありません(特殊文字をエコーするか、改行を防止します)。キャリッジ リターンを使用\r
または取得できる場合があります。\015
それらをシェルに認識させる必要-e
があるかもしれません(しかし、それはリテラルをエコーするだけかもしれません-e
)。スクリプト内にリテラル キャリッジ リターンを配置するとおそらく機能しますが、スクリプトの維持が面倒になります。
同様に-n
、改行を押しつぶす可能性がありますが、リテラルを単にエコーする可能性があります-n
。改行を押しつぶす最も初期の方法は、改行が自然に移動するecho
特別なシーケンスを使用していました。これは、 (Mac OS X のバージョンを含む) の一部のバージョンで、または bash の組み込みの echo オプションと組み合わせて\c
引き続き機能します。/bin/echo
-e
したがって、スクリプトの最も単純な部分のように見える部分は、awk
.