# Linux 標準教科書
# Linux とは
- UNIX --- AT&T, Ken Tompthon, System-V, BSD
- Linux --- UNIX と似て非なる GPL の OS
- カーネル --- OS の中核。ハードとソフトの橋渡しをする。
- ユーザランド --- OS のカーネル以外の部分。コマンドはここで動作する。
- シェル --- 対話型コマンド入力環境。コマンドの受付、シェルスクリプトの実行が 2 つの大きな役割。
# 基本的なコマンド
# ls
-t
最終更新時間で並べ替え-r
逆順ls *.conf
ワイルドカードls ???.conf
文字数指定のワイルドカード
# cp
-i
interactive-r
recursive フォルダも-p
所有者、属性、更新日時などを消さずに保持する
# mv
-i
-f
force 強制的に
# rm
-i
-f
-r
# pwd
カレントディレクトリのパスを表示
# mkdir
-p
上位フォルダもあわせて作成
# cat
-n
行番号を指定
# less
スペース
進むb
戻る/
検索q
終了
# find
find PATH -name FILENAME
# man
コマンドのみならず、システムファイルやカーネルなど様々なもののマニュアルを表示できる
man passwd
man 5 passwd
ジャンルを指定して検索
# touch
- 最終更新日時を変更する
- ファイルが存在しない場合は新規に作成する(こちらの目的で使われることが多い)
# head
, tail
-n
先頭|末尾から n 行分を表示-c
先頭|末尾から c バイト分を表示
tail
には特別なオブション-f
がある。これを使うとそのファイルをウォッチ(読み込み続けること)できる。ログを読む際などに使う。
# sort
テキストファイルの中身をソートする。
-r
逆順でソートする-k n
n 列目のデータを使ってソートする(列はスペース区切りで判定される)-n
数値として認識してソートする
# uniq
uniq FILENAME
前の行と重複している行を出力しない
# tr
標準入力からの文字列を置き換える(translate する)
cat SOMEFILE | tr 文字列1 文字列2
例えば
Android
iPhone
Windows Phone
をtr on ON
すると
ANdrOid
iPhONe
WiNdOws PhONe
になる
# diff
差分を出力する。2 つのファイルを比べたり、パッチを作ったりする時に使う。
-c
context diff 形式で出力-u
unified diff 形式で出力(git と一緒)
# grep
- ファイルの中からデータを探す。
grep ".*\.png$" FILENAME
- 標準入力からのデータを検索対象にすることもできる。
- regex が使える
-e
or 検索をしたいときに使うgrep -e ".*\.png$" -e "my.*\.jpg$" FILENAME
-i
大文字小文字の違いを無視する-v
マッチしない行を選択する
# 正規表現とパイプ
# 標準入出力
- 標準入力 - デフォルトでキーボード
- 標準出力 - デフォルトでディスプレイ
- 標準エラー出力 - デフォルトでディスプレイ
# リダイレクト
標準入出力の向き先を変えること。
1>
は標準出力をリダイレクト(1
は省略可)2>
は標準エラー出力をリダイレクト&>
は標準出力及び標準エラー出力をリダイレクト>&1
は標準出力「への」リダイレクト(&1
は省略可)>&2
は標準エラー出力「への」リダイレクト
# 入力
command < file # ファイルの内容をコマンドの標準入力に渡す
#-----------------------------------------------------------
# 出力
command >&2 # 標準出力を標準エラー出力にリダイレクト
command > file # 標準出力をリダイレクト
command >> file # 標準出力をリダイレクト(追記)
command 2> file # 標準エラー出力をリダイレクト
command &> file # 標準出力/エラー出力を同一ファイルにリダイレクト
command &>> file # 標準出力/エラー出力を同一ファイルにリダイレクト(追記)
command > file 2>&1 # 同上
command >> file 2>&1 # 同上
command > file1 2> file2 # 標準出力,エラー出力を別々のファイルにリダイレクト
command >> file1 2>> file2 # 標準出力,エラー出力を別々のファイルに追加書き込み
# vi エディタ
# コマンド
:q
終了:w
保存:wq
保存して終了:q!
保存せずに終了
# 移動
w|b
ワード送り0
行頭$
行末Ctrl-D|U
半ページ送りCtrl-F|B
ページ送りgg
文書頭G
文書末H|M|L
ページの上部・中部・下部へカーソルを移動:123
指定行へ移動
# 編集
dd|yy
カット、コピー5dd|5yy
複数行カット・コピーp|P
現在の行の後ろ or 前にペーストu
カット、ペーストを取り消し
# 検索
/文字列
検索n|N
前後の検索結果に移動
# 置換
s は sed の s
:123s/old/new
123 行目の最初の old を new に置き換え:123s/old/new/g
123 行目の全ての old を new に置き換え:%s/old/new
ファイル全体の最初 old を new に置き換え:%s/old/new/g
ファイル全体の全ての old を new に置き換え:%s/old/new/gc
ファイル全体の全ての old を new に置き換え(確認つき)
# 管理者の仕事
# グループとユーザ
/etc/passwd
ユーザの定義を記述するファイル/etc/group
グループの定義を記述するファイル/etc/shadow
パスワードを記録するファイル
これらのファイルの中身の読み方は本書のセクション 7 を参照すること。
# useradd
ユーザを作成する
-c
コメントを加える-g
プライマリグループを指定-G
補助グループを指定-d
ホームディレクトリを指定-s
シェルを指定 ログインしないユーザにはnologin
を指定する-u
ユーザ ID を指定
# usermod
ユーザを変更する。useradd
のオプションは全て使える。
-l
ユーザ名を変更する
# userdel
ユーザを削除する
-r
ホームディレクトリを削除
# groupadd
グループを追加
-g
グループ ID を指定する
# groupmod
グループを編集
-n
グループ名を変更-g
グループ ID を変更
# groupdel
グループを削除
# パスワード
昔は/etc/passwd
に記録、今は/etc/shadow
に記録される。
passwd ユーザ名
で設定する。
パスワードがセットされていないユーザはログインできない。
# su
コマンド
一時的に他のユーザになる。ユーザを指定しなければ root になる。
su
ユーザ切替(カレントディレクトリを変えずに)su -
又はsu - root
ユーザ切替(カレントディレクトリを root のホームディレクトリにする)
# sudo
コマンド
一時的に他のユーザ権限でコマンドを実行する。
-u
オプションでユーザを指定しなければ root になる。sudo
できるユーザグループをvisudo
コマンドで明示的に指定しておく必要がある。
# ユーザ権限とアクセス権
# 所有者と所有グループ
ファイルの作成者が所有者・所有グループになる。
# chown
所有者を変更する
-R
ディレクトリ内の全てを再帰的に変更する
# chgrp
所有グループを変更する
-R
ディレクトリ内の全てを再帰的に変更する
# アクセス権
# chmod
アクセス権を変更する。
# u --- user, g---group, o---other
chmod u+rw-x,go+r-wx SOMEFILE
chmod 600 SOMEFILE
# seduid ビット
これが設定されている場合は、他者が実行したとしても、ファイル所有者の権限で実行される。
chmod u+s SOMEFILE
# -rwSr--r-- 1 root root 0 Nov 19 00:43 idbitfile
# 実行権限も付与されている場合は小文字表記になる
# -rwsr--r-- 1 root root 0 Nov 19 00:43 idbitfile
# setgid ビット
これが設定されている場合は、他者が実行したとしても、ファイル所有グループの権限で実行される。
chmod g+s SOMEFILE
# -rw-r-Sr-- 1 root root 0 Nov 19 00:43 SOMEFILE
# 実行権限も付与されている場合は小文字表記になる
# -rw-r-sr-- 1 root root 0 Nov 19 00:43 SOMEFILE
# sticky ビット
これが設定されているディレクトリ内のファイルは所有者以外は削除できない。
chmod +t SOMEFILE
# -rw-r--r-T 1 root root 0 Nov 19 00:43 SOMEFILE
# 実行権限も付与されている場合は小文字表記になる
# -rw-r--r-t 1 root root 0 Nov 19 00:43 SOMEFILE
# umask
マスク値を表示したり、設定したりする。
デフォルトの値からマスク値を引いた値が、ファイルの権限になる。
例えば、touch は 666 の権限でファイルを作成しようとする。 しかし、マスク値が 022 なので、実際には 644 の権限で作成される。
# 現在のマスク値を表示
umask
# => 0022
touch SOMEFILE1
# -rw-r--r-- 1 root root 0 Nov 19 00:58 SOMEFILE1
# マスク値を000にする。シェル内でのみ有効。
umask 000
touch SOMEFILE2
# -rw-rw-rw- 1 root root 0 Nov 19 00:58 SOMEFILE2
# シェルスクリプト
# 基本
# シェルの指定
1 行目に#!/bin/bash
などで使用するシェルを指定する。
2 行目以降にコマンドを記述する。
# echo
引数として与えた文字列を標準出力に出力する。
-n
改行を出力しない
# 変数
代入は=
、参照は$
abc=123
echo $abc
# =>123
配列への代入は[]
をつけて行う。参照は${}
で行う。
arr[0]=5
arr[1]=6
echo ${arr[1]}
# =>6
# シェル変数
- シェル変数は、子プロセス(シェルから実行した他のコマンド)には引き継がれない。
set
で一覧表示(但し環境変数も含む)、unset
で削除する。
# 環境変数
- 環境変数は、子プロセス(シェルから実行した他のコマンド)にも引き継がれる。
env
で一覧表示、unset
で削除する。export
で設定する。
export abc # シェル変数abcを環境変数にする
export abc=123 # 環境変数abcを作成し123を代入する
# read
標準入力からデータを読み込んで変数に代入する。
read abc
# 'hello'と入力
echo $abc
# => hello
# 引用符
- シングルクォート --- 変数を展開せずに文字列になる。
- ダブルクォート --- 変数を展開したうえで文字列になる。
- バッククォート又は
$()
--- 変数を展開したうえで、コマンドとして即時に実行した結果が文字列になる。
filename="READ"
# シングルクォート
echo '$filename' # => $filename
# ダブルクォート
echo "$filename" # => READ
# バッククォート
echo `ls | grep $filename` # => README.md
# $()
echo $(ls | grep $filename) # => README.md
# 引数
$
のあとに番号や記号を指定することで引数を取得できる。
./args.sh aaa bbb ccc
# $0 => ./args.sh
# $1 => aaa
# $2 => bbb
# $3 => ccc
# 引数の数を取得する
# $# => 3
# shift
$2
を$1
に、$3
を$2
というふうに、引数の位置を手前に 1 つずつずらす。
# バックスラッシュによる改行
echo "I am a cat. Y
As yet I have no name."
# エスケープシーケンス
直後の 1 文字の扱いを変更する。
echo "I am a cat. \
As yet I have no name."
# => 改行は無効にして出力しない
echo "My name \"IS\" John"
# => 引用符を無効にしてただの文字列として扱う
echo -e "My name \t is \n John"
# => タブや改行を挿入する
# (`echo`でエスケープ文字を利用するには`-e`オプションの指定が必要)
# source
コマンド
指定したファイルを読み込んでシェル環境を設定する。例えば、.bashrc
の変更を再ログインせずに適用したい際などに使う。
# 条件分岐
# 条件式
条件式はtest
又は[]
で書く。下記の 2 つは等価である。スペースに注意する。
test -f FILENAME
test ! -f FILENAME
否定形[ -f FILENAME ]
[ ! -f FILENAME ]
否定形
# if
if 条件式; then
# 処理
elif 条件式; then
# 処理
else
# 処理
fi
# 文字列比較
[ a = b ]
等しい[ a != b ]
等しくない
# 数値比較
[ a -eq b ]
等しい[ a -ne b ]
等しくない[ a -ge b ]
a が b 以上[ a -le b ]
a が b 以下[ a -gt b ]
a が b より大きい[ a -lt b ]
a が b 未満
# ファイル属性の確認
[ -f FILENAME ]
ファイルである[ -d FILENAME ]
ディレクトリである[ -e FILENAME ]
ファイルが存在する[ -L FILENAME ]
シンボリックリンクである[ -r FILENAME ]
読み取り可能である[ -w FILENAME ]
書込み可能である[ -x FILENAME ]
ファイルが存在し、実行権限がある[ -s FILENAME ]
サイズが 0 より大きい
# 論理積、論理和
[]
の外に書くか中に書くかで書き方が異なる。
# 論理積
[ 条件1 -a 条件2 ]
[ 条件1 ] && [条件2]
# 論理和
[ 条件1 -o 条件2 ]
[ 条件1 ] || [条件2]
# case
animal="tiger"
case $animal in
"dog" )
echo "string is dog";;
"cat" | "tiger" ) # 複数条件にしたい場合
echo "string is cat or tiger";;
* ) # どの条件にも当てはまらなかった場合
echo "this is default"
esac
# 繰り返し
# for
for i in 1 2 3 4
do
echo $i
done
# コマンドの実行結果を処理対象にできる
for i in `ls`
do
echo $i
done
# while/until
while [ $count -le 10 ]
do
echo "$count 回目の処理です"
count=`expr $count + 1`
done
# select
ユーザに選択肢を提示して選ばせる時に使う。
select name in "apple" "orange" "banana"
do
echo "you selected $name"
done
# ctrl+C を押さない限り永遠に繰り返される
# continue, break
do-done
の中で使う。
continue
ループの先頭に戻る。break
ループを抜けて次に進む。
# サブルーチン
サブルーチン=関数のこと
# `function`は省略可能
function sayHello () {
echo "hello"
}
# 呼び出し方
sayHello # => "hello"
引数の使い方
sayHello () {
echo "hello, $1"
}
sayHello John # => "hello, John"
返値の使い方
sayHello () {
return 123
}
result=sayHello
echo $result # => 123
# tips
# チェーン
コマンド1 && コマンド2
--- コマンド 1 が正常終了したらコマンド 2 を実行コマンド1 || コマンド2
--- コマンド 1 が異常終了したらコマンド 2 を実行
[ -x /sbin/ip ] || exit 1
コマンド1 && コマンド2 && ... && コマンドN || コマンドY
--- コマンドを順に実行する。どこかで異常終了したらコマンド Y を実行する。
# 一時的な環境変数の上書き
実行環境の差によって結果がブレるのを防ぐためによく使われるテクニック。そのコマンドでのみ一時的に変数を書き換える。
[ "$(SOME_VALUE=1 some_command)" = "success" ]
# デバッグ
-x
オプションをつけることで、コマンドや変数の中身を表示しながら実行できる。
sh -x ./sample.sh
# ネットワーク
# コマンド類
traceroute www.google.co.jp
--- 経路確認ip a[ddress]
--- ネットワーク設定を表示ip route
--- ルーティングテーブルを表示ip route add|del
--- ルーティング設定の追加・削除nslookup www.google.co.jp
--- IP アドレスの参照nslookup 192.168.11.1
--- IP アドレスからホスト名を逆参照ss -at
--- TCP サービスを表示ss -au
--- UDP サービスを表示
# DNS
/etc/resolv.conf
--- DNS の設定/etc/hosts
--- 静的な名前解決の設定
# プロセス管理
# プロセス
プロセスとはLinux が実行中のプログラムを管理する単位のこと
- シェル自身もプロセスである
- シェルでコマンドを実行すると
- シェルは子プロセスとして自分の分身を作る(fork)
- 子プロセスでコマンドが実行される(exec)
- 子プロセスは、コマンドが終了すると親プロセスに終了を伝えて消滅する
# スケジューリング
- 厳密には、プロセスは同時に 1 つしか実行されない
- ラウンドロビン方式のスケジューリング
- プロセスは待ち行列(Run Queue)で待機する
- 順番が回ってきたら一定時間(タイムスライス)だけ処理を前にすすめる
- 次に順番が回ってくるのを待つ
- FIFO 方式のスケジューリング
- 優先度は Nice 値によって決まる。
nice
,renice
コマンドで設定する。
# ジョブ
ジョブとはシェルがプログラムを管理する単位のこと
# バックグラウンドで実行する
# はじめからバックグラウンドで実行する
tail -f &
# 途中でバックグラウンドに移行する
tail -f # Ctrl+Z
bg
# フォアグラウンドへ移行する
tail -f # Ctrl+Z
tail -f # Ctrl+Z
tail -f # Ctrl+Z
tail -f # Ctrl+Z
tail -f # Ctrl+Z
jobs
# [1] suspended tail -f
# [2] suspended tail -f
# [3] suspended tail -f
# [4] - suspended tail -f
# [5] + suspended tail -f
# 3番をフォアグラウンドジョブにする(どちらでも効果は一緒)
%3
fg %3
# -のついたジョブ(2つ前に操作したジョブ)をフォアグラウンドジョブにする(どちらでも効果は一緒)
%-
fg %-
# +のついたジョブ(1つ前に操作したジョブ)をフォアグラウンドジョブにする(どれでも効果は一緒)
fg
fg %+
fg %%
%+
%%
# ジョブを終了する
kill %%
など
# プロセス ID
ps
コマンドでプロセス ID の一覧を取得できる。l
オプション 親プロセスを取得e
オプション コマンドの後に環境を表示
- 自身のプロセス ID は
echo $$
で取得できる
# シグナル
信号の送出によりプロセスを制御する仕組み。
# シグナルの送信方法
- キー入力(Ctrl+Z 等)
kill
コマンド(kill -TSTP PID
)- プログラムで
kill()
関数を呼ぶ
key | シグナル番号 | シグナル名 | 意味 |
---|---|---|---|
Ctrl+C | 2 | INT | 割り込み プロセスは終了する |
Ctrl+\ | 3 | QUIT | 強制停止 |
15 | KILL | 終了 kill コマンドのデフォルト | |
Ctrl+Z | 18 | TSTP | 一時停止 |
# シグナルの補足
trap
コマンドでシグナルを補足できる。補足後は、補足した場所の次の行から処理が継続される。
trap 'echo "SIGINTが入力されました"' 2
# top コマンド
実行中のプロセスの状態をダイナミックに表示する
# ファイル管理
# Linux のファイル管理
- ファイルシステム --- 属性データ、ファイル本体を効率よく管理するための仕組み
- パーティション --- ハードディスクを区切った単位
# FHS (Filesystem Hierarchy Standard)
ファイルシステムの標準構成。下記のようなふわっとした決まりがある。
bin
--- 一般ユーザ用プログラムsbin
--- システム管理用プログラムetc
--- 設定ファイルlib
--- 複数のプログラムで共通に使われるライブラリvar
--- ログ、データベース、ウェブサイトなどの可変的データboot
--- 起動関連dev
--- デバイスhome
--- ユーザの作業領域tmp
--- 一時ファイル
/usr
や/usr/loacl
ディレクトリ以下にもほぼ同じ構成のディレクトリがあり、ユーザが独自にインストールするものはここに置くこともある。
# パーティション
- 基本パーティションと拡張パーティションはあわせて最大 4 つまで作成できる。
- 拡張パーティションは 1 つだけ作成できる。
- 拡張パーティションの中に「論理パーティション」をいくつも作成できる。
パーティションの管理はfdisk
で行う。詳細略
# ファイルシステム
- Linux では ext3、ext4 など。ext3 以降ではジャーナリング機能があるため障害に強い。
- Windows では NTFS,NTFS,exFAT など
- CD では ISO9660 など
# コマンド
df
--- 現在マウントされているファイルシステムを表示するmkfs
--- パーティションにファイルシステムを作成するe2label
--- パーティションに名前をつける
# マウント
- 1 つ目のディスクを必ずルートディレクトリ(
/
)にマウントする - 複数のディスクを使うときは、既にマウントされているディスクの中のディレクトリに重ねてマウントする
# mount
コマンド
# マウントのオプション
# -t タイプ ext3など
# -o オプション rw, roなど
mount /dev/sda1 /target
umount /target
# スワップ領域
mkswap デバイスファイル # スワップ領域の作成
swapon デバイスファイル # 有効化
swapoff デバイスファイル # 無効化
# 自動マウント
自動マウントしたい場合は/etc/fstab
に設定を記載する
mount -a
で上記に記載した全てのパーティションをマウントできる(ただし swap 領域を除く)
# リムーバブルメディア
mount -t iso9660 -o ro /dev/cdrom /media/cdrom
などして使う
# i ノード
- i ノード番号 --- ext ファイルシステムにおけるファイルを管理するための番号
- i ノード領域 --- ファイルのディスク上の位置やアクセス権などの情報を保持している領域。i ノード番号で管理する。この領域がなくなると新しいファイルを作成できない。
# iノード番号の確認
ls -i
# iノード領域の確認
df -i
# リンク
# ハードリンク
- i ノード番号を共有することで実現している
- ハードリンクを削除しても、同じ i ノードを指すハードリンクの数が 0 にならない限りは、元ファイルは削除されない。
- i ノードを基礎にしているため、別ファイルシステム(パーテイション)には作成できない
ln original_file link_file
# シンボリックリンク
- 元ファイルの場所を表す擬似的なファイルを作成することで実現している
ln -s original_file link_file
# ディスク管理
fsck
--- ファイルシステムのチェックと修復を行う。対象パーティションはアンマウントしてからチェックをかけることをおすすめ。du
--- ファイルやディレクトリの使用量を調べる