Shell 特殊変数


忘れるからメモ。Bash では [Special Parameters -- Bash Reference Manual](https://www.gnu.org/software/bash/manual/bash.html) という。 [2.5 Parameters and Variables -- opengroup.org](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05) Posix Shell はここらへん。

| 変数 | |
| -----: | :------ |
| $# | コマンドラインの引数 |
| \$1 〜 \$9, \$0 | 引数それぞれ。 [Positional Parameters](https://www.gnu.org/software/bash/manual/bash.html#Positional-Parameters-1) という。 |
| $* | \$0 以外のコマンドライン引数 |
| $@ | \$\* と同等。ただし "$@" とした時、位置パラメータを評価せずにコマンドに渡すことが出来る |
| $? | シェルが最後に実行したコマンドの終了状態を保持している。ほとんどのコマンドは成功時には「０」を返す |
| $$ | 現在のシェルのプロセス番号を保持している |
| $- | シェルにセットされているオプションを保持している |
| $! | バックグラウンドで実行された直前のプロセスのプロセス番号を保持しています |

## その他

[Shell Parameter Expansion -- bash](https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion-1) とか [2.6.2 Parameter Expansion -- posix shell](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02) とか、細かいところでハマりそうなところ。

|書き方||
| --: | :-- |
| \${@:2} | 二つ目以降の引数を取得 |
| `${parameter:-word}` | *parameter* が未定義/NULLのときは *word* が **代用** される |
| `${parameter:=word}` | *parameter* が未定義/NULLのときは *word* が **代入** される |
| `${parameter:?word}` | *parameter* が未定義/NULLのときは *word* とエラーを出力して終了する。 |
| `${parameter:+word}` | *parameter* が未定義/NULLのときは NULL を使用して、それ以外のときは *word* を使う |
| `${parameter%word}` | 最短の **接尾語** を取り除く。拡張子を消す等に使用。実行例を参考 |
| `${parameter%%word}` | 最長の**接尾語** を取り除く。実行例を参考 |
| `${parameter#word}` | 最短の **接頭語** を取り除く。ディレクトリパスから `$HOME` を消す時等に使用する。実行例を参考 |
| `${parameter##word}` | 最長の **接頭語** を取り除く。ディレクトリパスを消したい時に使用する。実行例を参考 |
| $'string' | **Bash のみ** <br />ANSI-C Quoting. `echo 'a\te';` としても `a\te` と表示されるが、 `echo $'a\te'` としたら `a	e` となる。 `\UHHHHHHHH ` と Unicode( ISO/IEC 10646 ) がある。 |

気が向いたら増やしてく。

### Shell Parameter Expansion の *:* のこと

**:-** とか使用するが、この **:** は変数定義と *NULL* で挙動がそれぞれ微妙に変わる。

| | Parameter 定義しNULL値ではない | Parameter定義しているがNULL値 | Parameter 未定義 |
|--:| --:|--:| --:|
| `${parameter:-word}` | parameter を返す | *word* を返す  | *word* を返す |
| `${parameter-word}`  | parameter を返す | **NULLを返す** | *word* を返す |
| `${parameter:=word}` | parameter を返す | *word* を代入する | *word* を代入する |
| `${parameter=word}`  | parameter を返す | **NULLを返す** | *word* を代入する |
| `${parameter:?word}` | parameter を返す | エラーを出力して終了 | エラーを出力して終了 |
| `${parameter?word}`  | parameter を返す | **NULLを返す**    | エラーを出力して終了 |
| `${parameter:+word}` | word を返す | NULLを返す | NULLを返す |
| `${parameter+word}`  | word を返す | **word を返す** | NULLを返す |

### 実行例 `:-`,`:=`,`:?`,`:+` の違い例

```shell
#!/usr/bin/env bash


echo ${hoge:-abc}
echo ${hoge}
echo "--- separator ---"
echo ${hoge:=abc}
echo ${hoge}
echo "--- separator ---"
use_this="hoge"
echo ${use_this:+is_null}
echo ${say_null:+ok}
echo "--- separator ---"
echo ${err:?wow}
```

出力

```
> sh shell_param_exp.sh
abc

--- separator ---
abc
abc
--- separator ---
is_null

--- separator ---
shell_param_exp.sh: line 14: err: wow
```

### 実行例 -- 接尾語・接頭語のこと

```shell
#!/usr/bin/env bash

hoge="${HOME}/hoge/bake/file.c"

echo 'original'
echo $hoge
echo ''

echo '${parameter%word}'
echo ${hoge%.c}.o
echo ''

echo '${parameter%%word}'
echo ${hoge%%file.c}new_file.o
echo ''

echo '${parameter#word}'
echo ${hoge#$HOME}
echo ''

echo '${parameter##word}'
echo ${hoge##*/}
```

実行結果

```shell
> sh shell_prefix_patterns.sh
original
/Users/yasui/hoge/bake/file.c

${parameter%word}
/Users/yasui/hoge/bake/file.o

${parameter%%word}
/Users/yasui/hoge/bake/new_file.o

${parameter#word}
/hoge/bake/file.c

${parameter##word}
file.c
```

# その他 Shell を書く上で必要なサイト

[ShellCheck](https://www.shellcheck.net/) がおすすめ。 Shell の文法ミスから改善案まで言ってくれます。

## 参考

- [参考 kanazawa-u.ac.jp](http://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/sh-text/sh/node30.html, "特殊なシェル変数")
- [Shell Command Language opengroup.org](http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html)
- [bash manual -- www.gnu.org](https://www.gnu.org/software/bash/manual/bash.html)