変数と引数
対象を変えるたびに、ファイルを開いている
スクリプトの中に /var/log/nginx と直接書いてしまうと、別のディレクトリを見たくなるたびにエディタを開いて書き換えることになります。それでは手で打つのと変わりません。値に名前を付けて、あとから差し替えられる形にします。
代入は = の前後にスペースを入れません。
ターミナル
logdir=/var/log/nginx
ls -1 "$logdir"スペースを空けて logdir = /var/log/nginx と書くと、シェルは logdir という名前のコマンドを実行しようとして command not found になります。ここは誰もが一度は踏みます。
取り出すときは頭に $ を付けます。前後の文字列とつなげるときは ${logdir} のように波括弧で囲むと、どこまでが名前かがはっきりします。
ターミナル
prefix=access
touch "${prefix}_2026.log"スペースの入った名前で、いきなり壊れる
シェルスクリプトでいちばん多い事故がこれです。
ターミナル
target="/tmp/my report"
ls $target # 壊れる
ls "$target" # 正しい囲まずに書いた $target は、値を取り出したあとに空白で切り分けられます。シェルからは ls /tmp/my report と打ったのと同じに見えるので、ファイルが 2 つあると解釈され、どちらも見つからないと言われます。
変数を取り出すときは常に "..." で囲む、と決めてしまうのが安全です。囲んだ中では $ が値に置き換わります。逆に、シングルクォート '$target' は置き換えを一切しないので、$ を文字としてそのまま出したいときだけに使います。
引数を渡し忘れても、黙って走ってしまう
外から渡した値は、左から順に $1 $2 として受け取れます。渡された個数は $# で分かります。
ターミナル
#!/bin/bash
dir="${1:-/var/log}"
ls -1 "$dir" | head -3${1:-/var/log} は「$1 が空なら /var/log を使う」という書き方です。渡し忘れても既定の場所を見に行くので、空文字のまま走って意味の取れないエラーを出すことがなくなります。
呼ぶときはスクリプト名のうしろに並べるだけです。
ターミナル
bash peek.sh /var/log/nginx値はコマンドの結果からも作れます。today=$(date +%F) のように $( ... ) で囲むと、中のコマンドを実行した結果が変数に入ります。日付入りのファイル名を組み立てるときの定番です。
このスクリプトは、引数を変えるだけで別のディレクトリに使い回せます。渡された値をそのままコマンドに流す以上、囲み忘れは実害に直結します。"$1" と書く癖をここで付けておいてください。
課題
- 変数 name に Linux を代入する
- echo で Hello, Linux を出力する