bashでの変数は宣言とか特に必要なくて、
参照時に変数名の頭に$をつける。
代入時は$いらなくて、=で代入だけどスペースはあけない。
使える文字は[0-9a-zA-Z_]。
$1,$2,...$nは特殊な変数でコマンド引数を参照できる。
$?は直前のコマンドの終了ステータスを返す。

ってのは超常識か。

実は$nとか$?以外にも特殊な変数がある。
#!/bin/sh
echo "\$0>"$0
echo "\$1>"$1
echo "\$*>"$*
echo "\$#>"$#
echo "\$$>"$$

$0は実行したコマンド。
$*は引数全部。
$#は引数の数。
$$はプロセスID。

実行してみるとこんなかんじ。
$ ./shtest02.sh foo bar hoge baka
$0>./shtest02.sh
$1>foo
$*>foo bar hoge baka
$#>4
$$>39410


この$0はちょっと注意が必要で、スクリプト名とかじゃなくてあくまで実行コマンド。
↑だと普通に相対パスで実行してっけど、仮にパスが通ってる場所で直接実行した場合は
shtest02.shってなるし、test02っていうシンボリックリンク張ってたらtest02って出る。
注意点としてbashコマンドで実行してもbashとはならずにshtest02.shが表示される。


あと変数のスコープ。
↑のように普通に代入しただけの変数はそのシェルのみで有効。
ちなみにそのシェルで存在する変数を確認するにはsetコマンド。
そのシェルに限定されない環境変数として存在する変数を確認するにはprintenvを使う。
$ cat shtest03.sh 
#!/bin/sh
VAL="hoge"
echo "val = "${VAL}
echo "set>"
set | grep 'VAL'
echo "printenv>"
printenv |grep 'VAL'

実行するとこうなる。
$ ./shtest03.sh 
val = hoge
set>
VAL=hoge
printenv>

printenvしてもVALの値がないことがわかる。
環境変数に反映させたい場合はexportを使う。
$ cat shtest03.sh 
#!/bin/sh
VAL="hoge"
export VAL
echo "val = "${VAL}
echo "set>"
set | grep 'VAL'
echo "printenv>"
printenv |grep 'VAL'

$ ./shtest03.sh 
val = hoge
set>
VAL=hoge
printenv>
VAL=hoge

表示されましたね!
ちなみにexport $VALとするとprintenvしても出てこないが普通にecho $VALすると値が表示される。これどういう状況なんだろう。。