読むだけでちょっと賢くなる、架空のまとめスレ

【疑問】スクリプトを作ったのに Permission denied。#! の行、引数の変数、終了ステータス【LPICレベル1】

17レスカテゴリ:Linux
1: 名無しさん

バックアップ用のスクリプト backup.sh を書いた
./backup.sh したら Permission denied で動かへん

2: 名無しさん

前提のおさらい。よく使う手順は関数にまとめられる。関数の中では引数を $1 などで受け取る

3: 名無しさん

>>1
実行権限がない。chmod +x backup.sh で付ける。付ける前は Permission denied で終了ステータス126やった
bash backup.sh のように bash に渡すなら、実行権限がなくても動く

4: 名無しさん

>>3
1行目の #!/bin/bash は何のため?

5: 名無しさん

>>4
シバン(shebang)。./backup.sh で実行したときに、どのプログラムで中身を読ませるかを決める。#!/bin/sh なら sh、#!/usr/bin/python3 なら Python

6: 名無しさん

>>5
#!/bin/nonexist にしたら cannot execute: required file not found で終了ステータス127。書いたプログラムがないと動かへん

7: 名無しさん

>>5
Debian の /bin/sh は bash じゃなくて dash。#!/bin/sh で bash だけの書き方を使うと動かんことがある。ディストリビューションによって /bin/sh が bash のこともあるから、bash の機能を使うなら #!/bin/bash と書く

8: 名無しさん

>>2
スクリプトの引数はどう受け取るん?

9: 名無しさん

>>8
$0 スクリプトの名前、$1 $2 … 引数、$# 引数の数、$@ と $* 全部の引数
10番目からは ${10}。$10 は $1 のあとに 0 が付いたものになる

10: 名無しさん

>>9
./args.sh "a b" c で試した
$# → 2
for a in "$@" → [a b] と [c] の2回
for a in $* → a と b と c の3回(クォートなしは空白で分かれる)

11: 名無しさん

>>1
終了ステータスって何?

12: 名無しさん

>>11
コマンドが終わったときに返す数。0 が成功、0 以外が失敗。直前のものは $? で見る
true → 0、false → 1、ls /nonexist → 2
スクリプトでは exit 3 のように返す値を決められる

13: 名無しさん

>>3
どこに置いたら名前だけで動く?

14: 名無しさん

>>13
PATH に入ってるディレクトリ。自分だけなら ~/bin、全員なら /usr/local/bin。所有者と権限も確かめる。他の人が書き換えられる場所に置いたスクリプトを root が動かすと危ない

15: 名無しさん

>>14
スクリプトに SUID を付けたら root で動く?

16: 名無しさん

>>15
Linux では動かない。execve の man に「Linux はスクリプトの set-user-ID と set-group-ID のビットを無視する」とある。特別な権限が要るなら sudo を使う

17: 名無しさん

>>12
chmod +x、1行目は #!/bin/bash、引数は $1 と "$@"、成功は 0。これで動いたわ

管理人のひとこと