実行権限とスクリプト
配布物に付いてきたスクリプトが、そのままでは動かない
手元に落とした setup.sh を ./setup.sh と打つと Permission denied が返る。中身はただのテキストなのに動きません。Linux では、ファイルを直接起動できるのは実行の権利が立っているときだけだからです。
紛らわしいのは、起動できない原因が 1 つではないことです。次の 3 つが全部そろって、はじめてスクリプトは動きます。
- そのファイルに実行の権利があること
- 1 行目に、どのプログラムで動かすかが書いてあること
- 書かれたプログラムが、実際にそのパスに存在すること
Permission denied なら 1 つ目、bad interpreter なら 3 つ目、と読み分けられます。
1 行目の #! が、動かすプログラムを決めている
ターミナル
#!/bin/bash
#!/usr/bin/env python3先頭 2 文字が #! の行はシバンと呼ばれ、この中身を動かすプログラムの置き場所を書きます。1 行目でなければ効きません。/usr/bin/env をはさむ書き方をよく見かけるのは、Python や Node のようにマシンごとに置き場所が違うものを、探してもらってから起動するためです。
Windows で編集したファイルを持ち込むと、行末に見えない文字が付いて /bin/bash ではない何かを探しに行き、bad interpreter になることがあります。エディタの改行の種類を LF にして保存し直すと直ります。
./ を付けないと見つけてもらえない
ターミナル
$ setup.sh
bash: setup.sh: command not found
$ ./setup.sh名前だけで打つと、シェルはあらかじめ決められた置き場所だけを探します。今いるディレクトリはそこに含まれていません。含めてしまうと、ls という名前の細工されたファイルが置かれたディレクトリに入っただけで踏んでしまうからです。目の前のファイルを動かすときは ./ を付けて、場所を明示します。
権利を足さずに動かす手もある
ターミナル
bash setup.sh
python3 report.py動かすプログラムのほうを先に書けば、スクリプトは引数として渡されたただのテキストとして読まれるので、実行の権利は要りません。読む権利だけで足ります。他人のリポジトリを一度だけ試したいときや、ファイルの権限を書き換えたくない場面で使えます。
ただしこの形では、シバンの行がただのコメントとして無視されます。中身が Python なのに bash で起動すれば当然エラーになるので、合ったプログラムを自分で選ぶ必要があります。
ひな形の準備と表示を読む
演習ではファイル作成と表示の整形を渡します。printf '%s\n' は引数を1行ずつ書き出し、> は出力をファイルへ保存します。たとえば確認用のファイルは次のように作れます。
ターミナル
printf '%s\n' '#!/bin/bash' 'echo "Ready"' > report.sh名前() { ...; } の形は複数のコマンドをまとめた補助関数です。名前をコマンドとして呼ぶと、中の処理が実行されます。次は権限のうち所有者の3文字だけを見る別の表示例です。cut -c 2-4 は2文字目から4文字目を取り出します。
ターミナル
show_owner() {
ls -l report.sh | cut -c 2-4
}
show_owner演習の show_permissions は先頭10文字を表示する準備済みの関数です。最初の chmod 644 も実行権限がない状態をそろえる準備なので、書き換えません。空欄には、何もせず成功するコマンドを置いてあります。その書き方は次のとおりです。
ターミナル
:ひな形のままでも実行できます。空欄だけを自分のコマンドへ置き換えます。
課題
- show_permissions で変更前の権限 -rw-r--r-- を表示する
- chmod +x /tmp/hello.sh で実行権限を追加する
- /tmp/hello.sh を直接実行して Hello を表示する。bash /tmp/hello.sh ではなく、ファイル自身を起動する