デバッグ

デバッグ

 作成したプログラムが思うように動作しない場合、どこに問題があるのかを調べる必要がある。これをデバッグといい、プログラムの所々に、変数を表示させるコードやプログラムの走行ルートを表示させるコードを埋め込む必要があり、非常に労力がかかる。

 よって、プログラム言語にはデバッグを支援するツールが用意されている。シェルスクリプトにもスクリプトデバッグモードで動かすためのコマンドが用意されている。

sh コマンド

 sh 自身はシェルを起動するコマンドだが、 -x オプションを付けて引数にシェルスクリプトを指定すると、コマンドや変数の中身を表示しながらスクリプトを実行する。

実行例 繰り返し処理で使用した sample.sh ファイルにて sh コマンドを実行してみる。

$ sh -x ./sample.sh
+ true
+ echo 'Continue? (y/n)'
Continue? (y/n)
+ read input
y ( yを入力する )

+ case $input in
+ continue
+ true
+ echo 'Continue? (y/n)'
Continue? (y/n)
+ read input
n ( n を入力する )

+ case $input in
+ break
$

シェルとシェルスクリプト 4  条件分岐、繰り返し、サブルーチン

条件分岐

 プログラミングでは、条件に剃って挙動を切り替える 「 条件分岐 」 を多用する。シェルスクリプトでも利用することができる。

if 文

比較などによる条件分岐を行う場合はif 文を利用する。

$ if 条件式1 then ... elif 条件式2 ... else ...fi

 elif と else は省略可能である。 elif は別の条件で判断したい場合に利用する。 else は条件に当てはまたなかった場合に実行される。if 文は fi で終了する。

条件式 if 文で利用される条件式
演算子 比較内容
a == b a と b が等しければ真
a != b a と b が等しくなければ真
数値比較を行う演算子
演算子 比較内容
a -eq b a と b が等しければ真 ( equal to )
a -ne b a と b が等しくなければ真 ( not equal to )
a -ge b a が b 以上であれば真 ( greater than or equal to )
a -le b a が b 以下であれば真 ( less than or equal to )
a -gt b a が b より大きい値であれば真 ( greater then )
a -lt b a が b 未満であれば真 ( less than )

ファイル属性の確認

 ファイル属性の確認は次のように行う。

$ if test -d パス ; then ...

 -d の部分がファイル属性確認の演算子にあたる。 -d はディレクトリであるかの判定を行うので、この if 文全体で、 「 パスがディレクトリであれば真の値を返す 」 という条件式になる。

 ファイルの属性確認演算子は以下のようなものが利用できる。

演算子 内容
-f ファイル名 通常ファイルなら真
-d ファイル名 ディレクトリなら真
-e ファイル名 ファイルが存在するなら真
-L ファイル名 シンボリックなら真
-r ファイル名 読み取り可能ファイルなら真
-w ファイル名 書き込み可能ファイルなら真
-x ファイル名 ファイルが存在して、実行権限があれば真
-s ファイル名 サイズが0より大ければ真

 なお、test コマンドは [] を使って記述することもできる。

$ if [ 条件節 ]; then ...
$ if test [ 条件節 ] ; then ...

複数の条件式を重ねる

 条件分岐指定いる場合、複数の条件を重ねることができる。条件Aと条件Bが同時に成立してい必要がある時は 「 条件Aかつ条件Bが成立 」 ということで、論理積 ( =AND ) が用いられる。

 同じく、 「 条件Aもしくは条件Bが成立 」 の場合は論理和 ( =OR ) が用いられる。シェルスクリプトにおいて、論理積論理和の書き方は2通り存在する。

論理積

 論理積は -a を用いる場合と、 && を用いる場合がある。

$ [ 条件A -a 条件B -a 条件C ] ...
$ [ 条件A ] && [ 条件B ] && [ 条件C ] ] ...

-a と && は、それぞれ [ ] の内側か外側かで、使われ方が変わることに注意する。

論理和

論理和を表す記号は -o と || である。

$ [ 条件式A -o 条件式B -o 条件式C ]...
$ [ 条件式A ] || [ 条件式B ] || [ 条件式C ]...

 論理積の時と同様に -o と || はそれぞれ [ ] の内側か外側かで使われ方が変わる。

一体多の条件式

 一体多の分岐を行うことを考えてみる。 if 文を用いた場合、一体多の分岐は以下のようになる。

if 条件式 then

elif 条件式 then

elif 条件式 then

fi

シェルスクリプトでは、case 文が用意されており、一体多の分岐が記述できるようになっている。

case 変数 in
         値A)
                                処理1;;
         値B)
                                処理2;;
esac

 変数の値が値Aである時、処理1が実行される。最後は case 文の逆からの記述である esac で終わることが重要である。値はパイプ ( | ) で区切って複数指定することもできる。

実行例

$ vi case.sh
( インサートモードで以下を入力 )
#!/bin/bash
  
case $1 in
        a|A)
                echo "引数にaまたはAが入力されました";;
        b|B)
                echo "引数にbまたはBが入力されました";;
esac

シェルスクリプトを実行する。

$ ./case.sh a
引数にaまたはAが入力されました

$ ./case.sh b
引数にbまたはBが入力されました

 また、どの値にもマッチしなかった場合の処理を記述するには、値にアスタリスク ( * ) を用いる。

実行例

$ vi defaultcase.sh
( インサートモードで以下を入力 )

#!/bin/bash

case $1 in
        1)
            echo "引数に1が入力されました";;
        2)
            echo "引数に2が入力されました";;
        *)
            echo "1,2以外が入力されました";;
esac

シェルスクリプトを実行する。

$  ./defaultcase.sh 1
引数に1が入力されました

$ ./defaultcase.sh 2
引数に2が入力されました

$ ./defaultcase.sh 0
1,2以外が入力されました
( どの条件にもマッチしない場合、値 * の処理が実行される )

繰り返し

 プログラミングにおいて、条件分岐と同じくらい重要な機構が繰り返しである。同じ処理を繰り返し行い、ある条件が成立した時に終了する、という形式が用いられる。シェルスクリプトで用いられる繰り返しは以下の3通りである。

for 文

  for 文は値を列挙し、それを対象に処理を繰り返す。

$ for 変数 in 値のリスト
do
  処理
done

 値のリストとは、文字を羅列したものもあれば、実行結果を使うこともできる。

実行例

$ for i in a b c d 
for> do
for> echo $i
for> done
a
b
c
d

 これは、値のリストとして、a b c d が渡され、i = a を行い echo $1 、次に $1 、次に...を繰り返した結果である。値のリストとしてコマンドの実行結果を使うことができ、以下のように、i に ls の実行結果を代入してループが実行される。

$ for i in `ls`
for> do
for> echo $i
for> done
Applications
Desktop
Documents
Downloads
HTML
CSS
JavaScript
...
while/until 文

 while 文は条件が成立している間ループを繰り返す ( 条件が成立しなくなったら終了 ) という処理で利用される。

 until 文はそれの反対で条件が成立していない間ループを繰り返す ( 条件が成立したら処理を終了 ) という用途で使われる。

$ while 条件式
do
  処理
done

$ until 条件式
do
  処理
done

 C言語の for 文のようなループ分をシェルスクリプトで実現するには、expr コマンドを用いてループカウンタ用の変数をインクリメント ( またはデクリメント ) しながら、while/until 文で処理を行う。

実行例

$ vi loop.sh

#!/bin/bash
  
count=1
while [ $count -le 10 ]
do
     echo この処理は $count 回実行されました
     count=`expr $count + 1`
done

 count=1 で、カウンタ用の変数 count に初期値1を設定する。while [ $count -le 10 ] で、シェル変数 count が10以下の間、処理を繰り返す。

シェルスクリプトを実行

$ ./loop.sh
この処理は 1 回実行されました
この処理は 2 回実行されました
この処理は 3 回実行されました
この処理は 4 回実行されました
この処理は 5 回実行されました
この処理は 6 回実行されました
この処理は 7 回実行されました
この処理は 8 回実行されました
この処理は 9 回実行されました
この処理は 10 回実行されました

select 文

   select 文はユーザに対して数値による入力を促す。

$ select 変数 in リスト
do
   処理
done

実行例

$ select name in "apple" "banana" "orange"
select> do
select> echo "You selected $name";
select> done
1) apple   2) banana  3) orange  
?# 1
You selected apple
?# 2
You selected banana
?# 3
You selected orange
( control + c で終了する )

繰り返しの制御

 break や continue を用いることで、繰り返しを制御することができる。break は繰り返しを終了して、continue は繰り返しの先頭に戻る役割がある。

実行例

$ vi sample.sh
( インサートモードで以下を入力 )

while true
do
 echo "Continue? (y/n)"
 read input
 case $input in
 n) break
    ;;
 y) continue
    ;;
 *) echo "Please input y or n."
    ;;
 esac
done

シェルスクリプトを実行する

$ ./sample.sh
Continue? (y/n)
y ( y を入力する )

Continue? (y/n) ( 繰り返しの先頭に戻る )
a ( a を入力する )

Please input y or n. ( どの値にもマッチしなかった場合の処理が実行される )
n ( n を入力すると終了する )

$

サブルーチン

 プログラミングをする上で、一連の処理をまとめて、再利用できるようにしたものを、サブルーチンと言う。サブルーチンは言語により様々な呼ばれ方をされていて、シェルスクリプトでは関数と呼ばれている。

関数

 関数は、引数と呼ばれるデータを与え、処理をして結果を返すという機能の集まりである。

$ function 関数名
{
  処理
}

$ 関数名()
{
  処理
}

 両者ともに働きは同じである。引数は、実行時に関数名に続けて記述する。引数は関数の内部で、$1 、 $2 で参照することができる。

return 文

 シェルスクリプトの関数で、結果を返すときはreturn 文を実行する。

$ return 変数名

 return 文を実行すると、関数内での処理はそこで終了し、変数が関数に呼び出され元に戻される。

シェルとシェルスクリプト 3 変数〜soureコマンド

変数

 プログラムをする上で、非常に重要な考え方が変数である。簡単に言うと 「 箱 」 で、中に数値や文字列が入る。シェルスクリプトプログラミングでは、変数に数値や文字列を代入し、それを利用することができる。変数の代入は 「 = 」 を使って行い、参照は 「 $ 」 を付けて行われる。

実行例 シェル変数の作成

$ abc=123
( 変数 abc を定義 ( 内容は123 ) )

$ echo $abc
123
( 変数 abc の内容を表示する )

 変数 abc に 123 を代入した。bash では、一次元の配列変数を使用することができる。要素は角括弧 [] で囲う。配列変数の内容を表示する場合は、$ の後ろに波括弧 {} で配列変数を囲う。

$ abc[0]=123
$ abc[1]=456
$ echo ${abc[0]}
123
( abc[0] の内容を表示する )

$ index=1
$ echo ${abc[$index]}
( abc[1] の内容を変数を使って表示する )

シェル変数と環境変数

 シェルには2種類の変数がある。シェル変数と環境変数である。

 シェル変数は、実行しているシェルの内部でのみ有効である。

 環境変数は、そこから実行されたコマンド内でも有効になる。環境変数はシェル変数から作成できる。

実行例 環境変数の作成

export コマンドを使って、環境変数を作成する。

$ export abc
( シェル変数 abc を環境変数 abc にする )

$ export xyz=234
( 環境変数 xyz を作成し、 234 を代入する )

 1つ目のコマンドでは環境変数を作成しているが、値は代入されていない。一方で2つ目のコマンドでは、234 という値が代入されている。

 次に、2つのスクリプトBBb.sh と CCC.sh を使い、シェル変数と環境変数の動作の違いについて確認してみる。

$  vi BBB.sh
( インサートモードで以下を入力 )
#!/bin/bash
xxx=123
export yyy=234
echo xxx=$xxx in BBB.sh
echo yyy=$yyy in BBB.sh
./CCC.sh

シェル変数 xxx に 123 を代入している。

環境変数 yyy に234 を代入している。

$ vi CCC.sh
( インサートモードで以下を入力 )
#!/bin/bash
echo xxx=$xxx in CCC.sh
echo yyy=$yyy in CCC.sh

シェルスクリプトを実行する。

$ ./BBB.sh
xxx=123 in BBB.sh
yyy=234 in BBB.sh
xxx= in CCC.sh
yyy=234 in CCC.sh

このスクリプトを実行した時、シェルスクリプト CCC.sh の中で xxx の値は表示されない。なぜならシェル変数は引き継がれないからである。一方で yyy は環境変数なので CCC.sh まで引き継がれ、値が表示される。

read コマンド

read コマンドは標準出力からデータを読み込む。既に変数にデータが入っていた場合、新しいデータに上書きされる。

$ read 変数名

実行例

$ echo $abc
123
( 変数 abc の値が表示される )

$ read abc
456
( 値を入力する )

$ echo $abc
456
( 変数 abc の値が書き換わっている )

シェル変数

 シェル変数の一覧を表示する場合は、set コマンドを利用する。また、削除する場合は unset を利用する。

実行例 シェル変数一覧表示と削除

$ set
( シェル変数が表示される ( 数が多いので省略 ) )

$ set | grep abc
( abcで始まるシェル変数のみ表示する )

abc=456

$ unset abc
( シェル変数 abc を削除する )

$ set | grep abc
( abcで始まるシェル変数のみ表示する )

$ ( シェル変数 abc は削除されたので、表示されない )

環境変数

 現在の環境変数の一覧を表示するには、env コマンドを利用する。また登録済みの環境変数を削除する場合は unset コマンドを利用する。

実行例

$ env
( 環境変数が表示される ( 数が多いので省略 ) )

$ env | grep xyz
xyz=234
( xyz を含む環境変数を表示する )

$ unset xyz
( 環境変数 xyz を削除する )

$  env | grep xyz
( xyz を含む環境変数を表示する )

$ ( 環境変数 xyz は削除されたので、表示されない )

引用符

 シェルスクリプトにおいて、文字列を引用符で囲むことができる。利用できる引用符には' ( シングルクォート ), " ( ダブルクォート )、 ` ( バッククォート ) があり、使用される引用符により囲まれた文字列の処理が異なる。

 シングルクォートで囲まれた文字列の中に、参照用の 「 $ 」 付きの変数がある場合、 「 $ 」 も文字列として認識されるため、変数は展開されない。

 ダブルクォートの場合、引用符内の 「 $ 」 付き変数は展開された文字列になる。

 バッククォートで囲まれた文字列はコマンドとして解釈され、この時 「 $ 」 付き変数があれば、それを展開した上でコマンドが実行される。引用符は入れ子が可能である。

実行例 引用符の動作確認

シングルクォートで囲むと $ が文字列として認識される

$ ABC = 123
(変数を定義)

$  echo 'Value of ABC is $ABC.'
Value of ABC is $ABC.
( $ABC が文字列として認識され、表示された )

ダブルクォートで囲むと $ は変数として認識される。

$ echo "Value of ABC is $ABC."
Value of ABC is 123.
( $ABC が変数として認識され、内容である123が表示された )

バッククォートで囲むとコマンドとして認識される

$ XYZ=`date`;
( バッククォート )

$ echo "It is $XYZ now."
It is 2021年 2月 2日 火曜日 14時19分06秒 JST now.
( $XYZ に dateコマンドの実行結果が表示される )

$ echo "It is `date`now."
It is 2021年 2月 2日 火曜日 14時22分56秒 JSTnow.
( ダブルクォートで全体の文字を囲み、バッククォートで囲んだ date コマンドを挿入して、変数 XYZ の代入を省略 )

引数

 シェルスクリプトでは、実行時にオプションを引数として参照することができる。引数は $1、 $2、...と $ の後に引数の番号を指定することで参照できる。

実行例 args.sh を作成して、引数呼び出しの動作を確認する。
$ vi args.sh
( インサートモードで以下を入力 )
#!/bin/bash

echo '$1:' $1;
echo '$2:' $2;
echo '$3:' $3;
echo '$0:' $0;
echo '$#:' $#;
$ ./args.sh aaa bbb ccc
$1: aaa
$2: bbb
$3: ccc
$0: ./args.sh
$#: 3
( $1~$3 は引数、$0 はコマンド名、$# は引数の数を示す )

shift コマンドの確認

 shift コマンドは引数の順序をずらす。shift を実行すると、$2 が $1 に、 $3 が $2 になる。

実行例 shift コマンドの確認

$ vi argsshift.sh
( インサートモードで以下を入力 )
#!/bin/bash
  
echo '$1:' $1;
echo '$2:' $2;
echo '$3:' $3;
shift
echo '$1:' $1;
echo '$2:' $2;
$ ./argsshift.sh aaa bbb ccc
$1: aaa
$2: bbb
$3: ccc
$1: bbb ( $1 が bbb に変わった )
$2: ccc ( $2 が ccc に変わった )

エスケープシーケンス

 プログラミング言語には、特別な扱いを受ける文字がある。例えば、 echo コマンドで 「 Value od ABC is "123". 」 のように "" ( ダブルクォート ) を出力する方法を考えてみる。

$ ABC = 123
$ "Value of ABC is "$ABC"."
Value of ABC is 123.
( $ABC を "" で囲っても "" が表示されない )

$ echo "Value of ABC is \"$ABC\"."
Value of ABC is "123".
( 表示したい "" の直前に \ をつけることで "" を表示できる )
$ echo 'Value of ABC is "$ABC". '
Value of ABC is "$ABC".
( 文字列全体を '' で囲むことでも "" を表示できる )

$ echo "Value of ABC is \$ABC."
Value of ABC is $ABC.
( ダブルクォートで囲んだ文字列内で $ を表示したい場合も直前で \ を記述することで可能になる )

 このようにシェルスクリプトでは、\ ( バックスラッシュ ) はエスケープ文字と呼ばれ、特別な文字で直後の一文字の扱いを変更する。使用する引用符との組み合わせで、文字の扱いを変えたい場合にも有効である。

 \ は改行コードにも有効である。 \ を行末に付与することで、文字列の途中で折り返すことができる。適切に改行を入れることでコマンドの視認性を向上できる。   実行例

$ echo "I am a cat. As yet I have no name."
I am a cat. As yet I have no name.

$ echo "I am a cat.\
> As yet I have no name."
I am a cat.As yet I have no name.
( 途中でバックスラッシュを入れても改行は無視され同じ結果となる )

バックスラッシュにより改行は、シェルスクリプト内でも使うことができる。バックスラッシュは本来 \ であるが、多くの日本語環境では ¥ と表示される。

実行例

$ vi escape.sh
( インサートモードで以下を入力 )
#!/bin/bash
  
echo "I am a cat.\
As yet I have no name."
$ ./escape.sh
I am a cat.As yet I have no name.

 バックスラッシュには他にも用途があり、次に続く1文字とセットで特別な意味を持つ文字俺つとする、エスケープシーケンスという手法がある。

 よく使用されるものとして \t ( タブ )、 \n ( 改行 )、 \ 000 ( 数字で8進数表記の文字 ) がある。

実行例 echo コマンドでエスケープした文字を解釈するオプション -e で試してみる。

$ echo -e "I am a cat. \nAs yet I have no name\041"
I am a cat. 
As yet I have no name!
( \n は改行に変わり、 \041 は ! に変わった )

source コマンド

 source コマンドは bash などのシェルの内部コマンドで、指定されたファイルを読み込んでシェル環境を設定する。ファイル内容はシェルコマンドと解釈して実行する。

 一般的な用途としては、シェルの環境設定ファイルである ".bash_profile" などを設定変更後、ログインし直さずに設定を現在のシェル上で有効にする場合に使われる。

実行例 setsh というシェルスクリプトを作成し、$abc という変数に xyz を定義して、 source コマンドで読み込んでみる。

$ vi set.sh
( インサートモードで以下を入力 )

"!/bin/bash
abc=xyz
echo $abc
$ echo $abc

( $abc には何も格納されていないので、何も表示されない )
$ ./set.sh
xyz
( スクリプト内で設定された変数 abc の値が echo で出力された )

source コマンドでset.sh を読み込む。

$ source set.sh
xyz
(スクリプト内で設定された変数 abc の値が echo で出力された )

source コマンドで読み込んだことにより、set.sh の終了後も変数 abc に値が格納されたままになる。

$ echo $abc
xyz

シェルとシェルスクリプト 2 シェルスクリプト

シェルスクリプト

シェルスクリプトの作成

 シェルスクリプトはテキストで記述する。lsとdateコマンドを実行するシェルスクリプトを記述してみる。

$ vi lsdate.sh
(lsdate というファイルを作成する)

インサートモードで以下のように記述する。その後保存して終了する。( ESC キーの後に :wq )

#!/bin/bash
ls
date

 1行目に利用するシェルの種類とそのコマンド位置を記述する。シェルには数種類あるが、今回は bash を使用する。1行目にシェルを指定、2行目以降に実行するコマンドを1行ず入力していく。

パーミッションの変更

 作成したシェルスクリプトを実行するには、パーミッションを変更してファイルの実行権限をつける必要がある。現在のシェルスクリプトに実行権限があるかどうか確認する。

lsコマンドでファイルのアクセス権限を確認する。

$ ls -l lsdate.sh
-rw-rw-r--  1 hoge  staff  20  2  1 14:17 lsdate.sh

実行権限を付与するために、chmod コマンドを実行する。

$ chmod u+x lsdate.sh
$ ls -l  lsdate.sh 
-rwxrw-r--  1 hoge  staff  20  2  1 14:17 lsdate.sh

これで、所有者に実行権限を与えることができた。早速実行してみる。

$ ./lsdate.sh
0072                HTML & CSS          Pictures            projects            umask0022           umasl0022
Applications            JavaScript          Public              ruby                umask0070           user
Desktop             Library             chownfile           sinatra             umask0072           vireplace.txt
Documents           Movies              idbitfile           test                umask020            名称未設定フォルダ
Downloads           Music               lsdate.sh           umask               umask022
2021年 2月 1日 月曜日 14時18分59秒 JST

./ というのはパス指定である。意味は 「 カレントディレクトリにある ( lsdate.sh を実行せよ ) 」 ということである。ls や cp を実行するときはパスが通っているので、このようなパス指定は必要ない。

 今回はカレントディレクトリにある特定のシェルスクリプトを実行するために、パス指定を行った。lsdate.shの中に記述された、ls コマンドと date コマンドが順に実行されたことがわかる。

コメント

 コメントとは、プログラム上に書く注釈のことである。シェルの場合は # で始まる行がコメントとして認識され、プログラムの実行時はコメントは無視される。コメントは多くの場合、プログラマーが記述したプログラムがどういった処理をするのかを記述したり、一時的に特定の処理を無効化 ( コメントアウト ) する場合に利用する。

先ほどのシェルスクリプトの一部をコメントアウトする。

$ vi lsdate.sh

#!/bin/bash
ls
#date

シェルスクリプトを実行する

$ ./lsdate.sh
0072                HTML & CSS          Pictures            projects            umask0022           umasl0022
Applications            JavaScript          Public              ruby                umask0070           user
Desktop             Library             chownfile           sinatra             umask0072           vireplace.txt
Documents           Movies              idbitfile           test                umask020            名称未設定フォルダ
Downloads           Music               lsdate.sh           umask               umask022
( date コマンドが無視されている。 )

echo コマンド

echo コマンドは引数で与えた文字列を標準出力に出力するコマンドである。

$ echo [ オプション ] 文字列

オプション

-n 
改行を抑制する。通常の出力は改行されるが、このオプションがあると、改行されない。

実行例

$  echo Message test
Message test
( echo コマンドで指定された文字列を表示する )

シェルとシェルスクリプト 1 プログラミング

シェル

 シェルとは貝殻という意味である。カーネルが提供する機能を操作する際にOSと対話的に操作する必要がある。シェルはOSの、特にカーネル部分を包み込んでいることからその名があり、対話機能を提供するものである。

 シェルはコマンドの入力を受け付け、そのコマンドを実行し、入力したユーザに対してその結果を返す役割がある。

シェルスクリプト

 繰り返し行う処理を自動化させる手段としてシェルスクリプトを書いて実行する方法がある。

プログラミング

 コンピュータに対して、指示を与え順番に実行させる機能をプログラムと言う。そのプログラムを作成することをプログラミングと言う。条件分岐や繰り返しなど制御機能を加えて実行することができる、これをシェルスクリプトと呼ぶ。

プログラムの要素

 プログラミングには、どの種類のプログラムでもいくつかの重要な構成要素が存在する。主な要素は以下の4つが挙げられる。

  • 順次実行
  • 条件分岐
  • 繰り返し
  • サブルーチン

ユーザ権限とアクセス権

ファイルの所有者と所有グループ

 ファイル作成者のユーザIDとグループIDがファイルの所有者と所有グループとなる。所有者と所有グループはファイルの情報としては重要な属性である。所有者は chown コマンドで変更でき、所有グループは chgrp で変更できる。

所有者の変更

 ファイルの所有者を変更するには chown コマンドを使う。

$ chown ユーザ[.グループ ] ディレクトリ
$ chown ユーザ[.グループ ] ファイル

 ユーザとグループを変更するには root ユーザである必要がある。ディレクトリとファイルは区別なく変更できる。ユーザとグループの区切りに : を使うことも可能である。

オプション

-R ディレクトリを対象にする、ディレクトリの中のディレクトリやファイルを再帰的に変更する。
再帰的 

ディレクトリの中にディレクトリがあれば、中のディレクトリを全て辿る

所有グループの変更

 ファイルの所有グループを変更するにはchgrp コマンドを使う。

$ chgrp グループ ディレクトリ
$ chgrp グループ ファイル

 グループを変更できる。ディレクトリとファイルは区別無く変更できる。

オプション

-R 
ディレクトリを対象にする。ディレクトリの中でディレクトリやファイルを再帰的に変更する。

ファイルとアクセス権

 ファイルは 「 ファイルを所有するユーザ 」、「 ファイル所有グループからファイル所有者を除いたユーザ 」、「 その他のユーザ 」 と3つのレベルで権限を設定できる。

 ファイルにはユーザで分けた3つのレベルごとに 「 読み 」、「 書き 」、「 実行 」 の3つの権限が存在する。ファイルのモードを変更するには、chmod コマンドを使う。

ファイルに設定できるアクセス

 ファイルのモードとしては読み、書き、実行の3つの権限がある。所有ユーザ、所有グループで所有者以外のユーザ、所有グループ以外のユーザごとに3つの権限を設定できる。

 ls コマンドに -l オプションを付けて表示される1つ目のカラムがファイルのモードを示している。モードを表す1つ目のカラムは次の様になる。

linux 01

ファイル種別のr,w,x の意味
記号 意味
r 読み込み
w 書き込み
x 実行、またはディレクトリの移動

 rwx はユーザとグループとその他の3つに対して指定できる。r が表示されればファイルの読み込みが可能で、w が表示されればファイルの書き込みが可能である。 w が表示されれば、ファイルをプログラムとして実行できるか、またはディレクトリであればディレクトリへ移動できる。

実行例 サンプルファイルを作成する

$ touch user

ls コマンドの -l オプションで確認する

$ ls -l user
-rw-r--r--  1 hoge  staff  0  1 27 14:19 user
( 所有者が読み書き、所有グループが読み、その他が読みになっていることがわかる )

アクセス権の変更

 ファイルのアクセス権を変更するには chmod コマンドを使う。

$ chmod モード[,モード]...ディレクトリ 
$ chmod モード[,モード]...ファイル
$ chmod 8進数表記のモード ディレクトリ 
$ chmod 8進数表記のモード ファイル 

 ファイルのモードを所有ユーザと所有グループとそれ以外のユーザについて設定する。モード指定の書き方で次の2通りの記述方法がある。

  • モードの書式を複数書き、間まで区切って指定

* 8進数3桁で各ユーザのレベルを指定

オプション

-R
ディレクトリを対象にする。ディレクトリの中のディレクトリを再帰的に変更する。

linux 02

 モードは次の様に u ( 所有ユーザ ) 、 g ( 所有グループ ) 、 o ( その他 ) に対して、r ( 読み )、 w ( 書き )、 x ( 実行、またはディレクトリの変更 ) を設定したり ( = )、加えたり ( + )、取り消したり ( - ) できる。

 u,g,o の全てに同じ権限を指定する時は a を指定する。

ファイルモードの変更

実行例1 サンプルファイルを作成しモードを確認する。

$ touch chownfile
$ ls -l chownfile
-rw-r--r--  1 hoge  staff  0  1 27 15:20 chownfile

 -rw-r--r-- を -rw-rw-r-- に変更したい場合は、グループにw (書き) を加えたいので、g+w とする。

 -rw-rw-r-- を -w-rw-rw- に変更したい場合は、ユーザの r (読み) を取り除き、その他に w (書き) を加えたいので、 u-r,o+w とする。

 -w-rw-rw- を -w-rwxrwx に変更したい場合は、グループとその他に x (実行) を加えたいので go+x とする。

実行例2 グループに w ( 書き ) を追加する
$ chmod g+w chownfile
( グループに w ( 書き ) を追加 )

$ ls -l chownfile
-rw-rw-r--  1 hoge  staff  0  1 27 15:20 chownfile
実行例3 ユーザから r ( 読み ) を削除して、その他に w ( 書き ) を追加する
$ chmod u-r,o+w chownfile
( ユーザから r ( 読み ) を削除して、その他に w ( 書き ) を追加 )

$ ls -l chownfile
--w-rw-rw-  1 hoge  staff  0  1 27 15:20 chownfile
実行例4 グループとその他に x ( 実行 ) を追加する
$ chmod go+x chownfile
( グループとその他に x ( 実行 ) を追加 )

$ ls -l chownfile
--w-rwxrwx  1 hoge  staff  0  1 27 15:20 chownfile

ファイルモードを8進数で変更する

 -rw-rw-r-- としたい場合は8進数の664を指定し、--w-rw-rw- としたい場合は266を指定し、 --w-rwxrwx としたい場合は277を指定する。

サンプルファイルのファイルモードを元に戻す
$ chmod u+rw-x,go+r-wx chownfile
( ファイルモードを 「 rw-r--r-- 」 に変更している )

$ ls -l chownfile               
-rw-r--r--  1 hoge  staff  0  1 27 15:20 chownfile
ファイルモードを664に変更する
$ chmod 664 chownfile
( ファイルモードを664 に変更 )

$ ls -l chownfile  
-rw-rw-r--  1 hoge  staff  0  1 27 15:20 chownfile
ファイルモードを266に変更する
$ chmod 266 chownfile
( ファイルモードを266に変更 )

$ ls -l chownfile
--w-rw-rw-  1 hoge  staff  0  1 27 15:20 chownfile
ファイルモードを277に変更する
$ chmod 277 chownfile
( ファイルモードを277に変更 )

$ ls -l chownfile
--w-rwxrwx  1 hoge  staff  0  1 27 15:20 chownfile

 8進数で変更する場合、記述が短いが設定値を覚えていないとわかりにくい。一方で通常の変更はわかりやすいが記述が長い。

linux 02

 モードの指定にsetuid ビットと setgit ビットとsticky ビットという特殊な属性がある。setuid ビット、あるいはsetgid ビットがついたプログラムで実行すると、ファイル所有者あるいは所有グループの権限で実行される。

 具体的には、root ユーザ所有で setuid ビットがセットされたプログラムは、一般ユーザが実行した場合でも root ユーザが実行した場合と同じ動作をする。

 sticky ビットが付いたディレクトリ内のファイルは所有者以外が削除できなくなる、 ( Linuxではファイルについてのスティッキービットは無視される。 ) Linuxでは一般的に /tmp ディレクトリにスティッキービットが付与される。

ファイルモードで setuid/setgid/sticky の変更・確認

サンプルファイルを作成し、ファイルモードを確認する

$ touch idbitfile

$ ls -l idbitfile
-rw-r--r--  1 hoge  staff  0  1 27 16:45 idbitfile
setuid ビットを追加する
$ chmod u+s idbitfile
( setuid ビットを追加 )

ls -l idbitfile
-rwSr--r--  1 hoge  staff  0  1 27 16:45 idbitfile
setuid ビットを削除し、 setgid を追加する
$ chmod u-s,g+s idbitfile
( setuid ビットを削除し、 setgid を追加 )

$ ls -l idbitfile
-rw-r-Sr--  1 hoge  staff  0  1 27 16:45 idbitfile

3sticky ( スティッキー ) ビットを追加する。

$ chmod  +t idbitfile
( sticky ( スティッキー ) ビットを追加 )

$ ls -l idbitfile
-rw-r-Sr-T  1 hoge  staff  0  1 27 16:45 idbitfile

ファイル作成のモード

 ファイルを新規に作成するとユーザごとに規定されたパーミッションである644、または664といったパーミッションが設定されてファイルが作成される。

 umask コマンドを使うことで、指定したパーミッションでファイルを作成することができる。

$ umask [8進数のモードのマスク値]

現在のマスク値を表示

 umask コマンドに続けてマスク値を設定しなかった場合、現在のマスク値を表示できる。

マスク値の変更

 umask コマンドに続けてマスク値を設定すると、指定されたパーミッションでファイルが作成される。umask コマンドは指定しないビットを指定できる。

 umask コマンドで指定できるマスク値は、全てのユーザが読み書きできるパーミッション660から、指定したいパーミッションを引き算することでマスク値を求めることができる。

例 umask を変更してファイルを作成

$ umask 
022
(現在のマスク値を取得)
$ touch umask0022
( ファイルを作成 )

$ umask 070
( マスク値を070に変更 )

$ touch umask0070
( ファイルを作成 )

$ umask 072
( マスク値を変更 )

$ touch umask0072
( ファイルを作成 )

$ ls -l umask00*
-rw-r--r--  1 hoge  staff  0  1 31 15:10 umask0022
-rw----rw-  1 hoge  staff  0  1 31 15:10 umask0070
-rw----r--  1 hoge  staff  0  1 31 15:11 umask0072

 touch コマンドはモードが0666のファイルを作ろうとするが、umaskによりマスクされるために上記のモードのファイルができる。

-S オプションをつけるとモードを表示、または設定するとき、8進数ではなく意味が分かり易い形式を使用できる。

$ umask -S
u=rwx,g=rx,o=rx
( 現在のマスク値を表示 )

$ touch umask0022
(ファイルを作成)

$ umask -S u=rw,g=,o=rw
( マスク値を070に変更 )

$ touch umask0070
( ファイルを作成 )

$ ls -l umask00*
-rw-r--r--  1 hoge  staff  0  1 31 15:19 umask0022
-rw----rw-  1 hoge  staff  0  1 31 15:23 umask0070

 umask コマンドによるモードの制限は、umask コマンドを実行したシェル内でしか有効でないことに注意する。デフォルトのモードは.bashrc等のログインシェル内で設定することができる。

用意されているユーザとグループ

用意されているユーザとグループ

 Linuxはインストールしてすぐにそのシステムを利用できるように、ユーザとそのユーザが所属するグループが用意されている。

一般のユーザとグループ

 Linuxにログインするにはアカウントが必要である。アカウントを作成するとユーザ名と同様の名前のグループが作られ、ユーザはそのユーザグループに所属しているとシステムに登録される。

 グループは複数のユーザをまとめるためにある。グループを使うことで、システム上にあるディレクトリのアクセス権を設定し、 「特定のユーザにのみアクセスできるディレクトリファイルの作成する」 などといった使い方や、特定グループに属しているユーザのみ root ユーザになることができるような運用が可能となる。

rootユーザ

 root ユーザはシステム設定の変更や、プログラムのインストールや削除、ユーザを作成、削除することができる利用に制限のない特別なユーザである。

 root ユーザはアクセス権に関係なく、全てのユーザのディレクトリへのアクセス、コンテンツの読み書きが行えるなどの点で他の一般ユーザとは異なる。

su コマンド

 su コマンドは既に別のユーザでログインしているユーザが、一時的に他のユーザになるためのコマンドである。su コマンドを実行する際に、オプションとしてユーザを指定しない場合は root ユーザでシェルを起動する。

オプションを付けずに su コマンドを実行した場合はカレントディレクトを変更せずに root ユーザでログインする。カレントディレクトリを root のホームディレクトリに変更してログインする場合は 「 su - 」 もしくは 「 su -root 」 と実行することでカレントディレクトリを変更した上で root ユーザでログインできる。

 root ユーザでログインすると、システム管理用のコマンドを実行することができる。複数人でLinuxシステムを管理している場合は、root ユーザで直接ログインして作業すると、root ユーザとしての履歴だけが残り、誰がどんな作業をしたのか履歴が残らない。

 一方で、一般ユーザから root ユーザへ切り替えると、 root ユーザで作業を開始した時間などは直ぐに分かる。よって、安全や管理を考えると、一般ユーザでログインしてから root ユーザの権限を取得し、システム作業することが望ましい。

$ su
$ su - [ユーザ]

オプション

su - ( もしくは su - root )
root ユーザになることができる。

su - user
指定したユーザになることができる。

root ユーザでコマンドを実行する sudo コマンド

 sudo コマンドを使えば、スーパーユーザ ( root ユーザ ) 権限でコマンドを実行できる。su コマンドでユーザを root に切り替えることなく、 root 権限が必要な設定やプログラムを実行することができる。

 -u オプションを付けて sudo コマンドを実行すると、任意のユーザでコマンドを実行できる。オプションを付けないで sudo コマンドを実行した場合は root 権限でコマンドを実行する。

 sudo の設定は /etc/sudoers ファイルを編集することでユーザが sudo コマンドを実行できるようになる。/etc/sudoers ファイルは visufo コマンドを実行すると編集できる。

$ sudo コマンド
スーパーユーザ ( root ) 権限でコマンドを実行

$ sudo cat /var/log/message

オプション

-u ユーザ
指定したユーザでコマンドを実行する。