Personal tools
You are here: Home 原稿・資料 ワークス、アリエル共同勉強会 Unixコマンド生活実践
Document Actions

Unixコマンド生活実践

Unixで生活する上の実践的な知識を説明します

これは何か

  • Unixで生活する上の実践的な知識を説明します。
  • 普段使うコマンドを説明します。
  • シェルはbashを前提にしています。

ディレクトリ移動

.と..は常識なので省略

pwd   ...カレントディレクトリの表示(pwd:print working directory)
cd    ...ホームディレクトリに戻る
cd ~  ...同上
cd -  ...直前にいたディレクトリに戻る

pushdとpopdは一時使っていましたが、個人的には最近使わなくなりました(試して気に入れば使ってください)。

ファイル操作

空ファイルを作る時に使う
touch filename  
cp /dev/null filename

ファイルの情報を表示
stat filename

ディレクトリ操作

lsの使うオプション ...-l,-a,-F,-i

# ディレクトリをすべて消す場合(先頭の\は後述)
\rm -rf ディレクトリ名

# 全部コピー
cp -ar srcdir destdir   ...-aはGNU lsのオプション

# cp -aがどこまで信用できるか不明、あるいはGNU lsがない時に、使うテクニック
tar cf - srcdir | (cd /destdir; tar xf -)

ファイル操作(リンク)

ハードリンク vs. シンボリックリンク

ln     #ハードリンク  ...異なるファイル名で同一のi-nodeを共有(ls -iで確認可能)
ln -s  #シンボリックリンク  ...ポインタ

注意点

  • ハードリンクは対称(ln a bでもファイルaとbに主従関係はない)
  • i-nodeはデバイス(dfで見えるディスクデバイス)で一意なので、デバイスを越えてハードリンクは作れない
  • シンボリックリンクは指定したファイルパスを持っているだけ。相対パスで指定すれば相対パスとしてリンクするので注意。

ファイル操作(アーカイブ)

なんでもtar。GNU tarだとコマンドラインオプションでそのままgzipやbzip化できます。

tar zcf srcdir.tar.gz ./srcdir    #相対ディレクトリ指定の方が安全
tar ztf srcdir.tar.gz             #中身を見る
tar zxf srcdir.tar.gz             #展開

# zをjに変えるとbzip
tar jcf srcdir.tar.bz ./srcdir    #たいていgzipより圧縮率が良いようです(でも送り先の相手がbunzipできないかも)

GNU tarがない時、パイプを使います

tar cf - ./srcdir | gzip - > srcdir.tar.gz
gunzip -c srcdir.tar.gz |tar xf -

Unixのディレクトリ構成

歴史的なディレクトリ

/etc   #この下のファイルをどれだけ知っているかでUnixマニアぶりが分かります(/etcを見てバージョンまで含めてOSが分かれば通)
/sbin  # 歴史的にはstatic linkした実行ファイルを置くディレクトリでしたが、今や管理者用コマンドを置くディレクトリ
/dev   # 昔はmknodでデバイスファイルを手動で作ることもありましたが、今やコマンドラインから使うのは/dev/nullと/dev/zeroぐらい
/usr/local   #パッケージ管理全盛の今、手動インストールしたプログラムの置き場
/var         #/varはログファイルなどでディスクフルになりやすいので、/(ルート)とパーティションを分ける、という流儀もあります
/opt         #SVR4(Solarisなど)派の人が手動インストールしたプログラムを置く場所
/lost+found   #fsckで行き場を失ったファイル(要はディレクトリ破壊)が移動させられるディレクトリ(ディスクデバイスごとにひとつ)

新興ディレクトリ

/root   #rootユーザのホームディレクトリ
/proc   #Solaris発祥、Linux追随。かなり便利。とりあえずファイルの中を見るべし

環境変数に注意

はまりがち(自分のところと他の人のところで動きが違う。suで別ユーザ権限にしたら動きが違う。など)

env    #現在の環境変数の一覧
echo $PATH   #特定の環境変数の値を表示
su -   #suした対象ユーザのログイン時と同じ環境変数になるので、たいてい、この方が安全(今時はsudoの方が人気)
su - -c コマンド   #suしてコマンド実行する場合
  • ちなみに環境変数とは、子プロセスに引き継がれる変数のこと
  • 環境変数にまつわるFAQ (sh ~/.bash_profileしても環境変数が反映されない => 理由を答えられること)
  • 環境変数PATHにカレントディレクトリを含めると素人判定されるのでやってはいけません

便利な環境変数

export IGNOREEOF=-1
export HISTSIZE=65535
export HISTFILESIZE=65535
export HISTCONTROL=ignoredups

aliasの活用

他の人のaliasを盗むべし

# 伝統のalias
alias ls='ls -aF'
alias rm='rm -i'
alias mv='mv -i'
alias cp='cp -i'
alias ll='ls -l'

-iでうっかりミスを防げますが、鬱陶しい時もあるので、回避したい場合、rmのようにバックスラッシュをつけるのが便利(/bin/rmでもOK)

# aliasの確認
type ls

manとinfo

とりあえずman。infoはGNU発祥です。

man -k keyword     #キーワード検索(あまり使えない...)
man 2 write        #セクションを指定。セクションの意味はman man(1,2,3は常識)

readline(コマンドラインの編集)とhistory

他の人の.inputrcを盗むべし

~/.inputrc
"\C-n":history-search-forward
"\C-p":history-search-backward
set show-all-if-ambiguous on
!!    #直前のコマンド
!ma   #maで始まる直前のコマンド

コマンドプロンプトのカスタマイズ

  • 環境変数PS1で色々遊べます。
  • 好みに応じて
  • 個人的に昔はカレントディレクトリを表示する流儀でしたが、プロンプトの長さが変化するのが嫌で最近はしていません

ファイルの検索

locate   #ファイル名のパターンで検索。意外に使える(インデックス構築処理があるので、作った直後のファイルは検索対象外)
find     #奇天烈コマンドの王様

find

find . -name foo
find . -name foo ! -type d     #and条件
find . -name foo -o ! -type d  #or条件
find . -name foo -exec cp /tmp/foo {} \;   #{}が見つかったファイルパス名に置き換わってコマンド実行 \; でコマンド終端
find . -type f | xargs tail    #xargsは標準入力をコマンドラインオプションに分配するコマンド

find and for

少し複雑な場合、-execオプションよりforに渡す方が簡易に書けます。

for f in `find . -type f`
do
  sed 's/foo/bar/g' $f > $f.bak
  mv $f.bak $f
done

プロセス

通常のプロセス起動状態を知っておくと、異常な状態の時に見分けがつくので、普段を知っておくべきです。

ps ax
pstree -p

プロセスkill

kill プロセスID
killall プロセス

Unixのプロセスを殺す方法はシグナル(一覧はman 7 signal)を送ることで実現します。なるべく穏便(=正常な終了処理をする)な死に方をするシグナルから試します。

SIGHUP  1    #伝統的にサーバ系ソフトは設定ファイルの再読み込み処理に割り当てていることが多いです
SIGINT  2
SIGTERM 15
SIGKILL 9    #これは最後に試す

メモリ

メモリ容量に関しては、swap領域の使用量を見るのが基本です(実メモリの使用量はほとんど気にしなくてよいです)

# よく使うコマンド
top
vmstat 5
free  

screen

誰かの.screenrcをもらうこと

ページャ

cat     #本来はファイル連結用コマンド(splitで分割してcatで連結)
more
less
view    #実体はviのハードリンク(read-only)。argv[0]でモード切り替えをする古典的テクニック
lv
tac     #catの逆向き

作業ログ

script /tmp/record

すべてのシェル上のやりとりがファイルに記録できます。

command | tee /tmp/record

commandの標準出力を画面とファイルの両方に出力できます。

ログを見る時の基本

ls -lrt   #最後に更新されたログファイルを見つけたい時
tail -f logfile    #基本テクニック

tail -fでも画面からあふれる時の端末制御

  • ctrl-sで停止、ctrl-qで再開

ログを見る時の基本(2)

大量に出ている同じメッセージを探す

sort logfile | uniq -c | sort -rn | head

man sortは見ておいた方が良いです

grep

# よく使うオプション
grep -r    #ディレクトリを再帰的にgrep (GNU grep拡張)
grep -i    #大文字小文字無視
grep -An   #nは数値。マッチした行の後(after)も表示
grep -Bn   #nは数値。マッチした行の前(before)も表示
grep -c    #マッチした行の行数(count)
grep -v    #マッチしない行を表示

sed

ちょっとした文字列置換には便利

command | sed 's/old/new/g' | ...
  • oldは正規表現
  • /が多い文字列を置換する場合、別の任意の文字(barや!がよく使われます)を区切り文字に使えます。
command | sed 's|old|new|g' | ...

sed(2)

一部を切り出す処理も、典型的な場合は定石を使って条件反射的に書けます。

例えばdovecotのimapのログから名前の部分を取り出すsed

dovecot: Jul 24 17:45:57 Info: imap-login: Login: user=<hana>, method=PLAIN, rip=1.2.3.4, lip=4.3.2.1

grep imap-login dovecot.log | sed 's/.*user=<\([^>]*\)>.*/\1/g'

定石(sedのs/A/B/gのAの部分を分解)

.*
適当にexactマッチしそうな文字列    ...上の例では user=<
\(                             ...グルーピングのためのカッコ(要エスケープ)
[^X]                           ...Xの部分は取り出したいパターンの終端文字。上の例では >
*\)X                           ...X以外の文字の繰り返しとグルーピングのためのカッコ
.*

sed(3)

応用

名前とIPアドレスの両方を取り出して順序を逆転して出力するsed

sed 's/.*user=<\([^>]*\)>.*rip=\([^,]*\),.*/\2 \1/g' 

awk

特定のカラムを抜き出す時には便利です。cutコマンドは意外に使いづらいので、awkの方が楽です

command | awk '{print $2,$3}' | ...

カンマ区切り(CSV)の場合、区切り文字をデフォルトの空白文字(スペースやタブ)から変更します。

command | awk -F, '{print $2,$3}' | ...

マッチした行に対してカラムの値で演算する、ぐらいはawkが楽です(これ以上複雑なことをするならperlでいいかも)。

command | awk '/マッチするパターン/{print $2,$3,$2+$3}' | ...

join

まれに使うjoin(RDBの文脈で使うjoin処理のこと)。一応、awk,join,catでSQLのselect,join,unionらしきことができます。

0 foo
1 bar
2 baz
と
0 FOO
1 BAR
3 BAZ
から
0 foo FOO
1 bar BAR
を得られる(join -1 1 -2 1 input1 input2)

testコマンド

testコマンドは別名で [ コマンドでも使えます(普通、シェルの組み込みコマンド)。

ファイルのチェックなどに使うことがあります。

[ -e /tmp/foo ] || touch /tmp/foo    #ファイルが無ければ作る
[ -e /tmp/foo ] && /bin/rm /tmp/foo  #ファイルがあれば消す

man test を参照

リダイレクト

読み方

  • 0:標準入力、1:標準出力、2:標準エラー出力 (0,1,2などはファイルディスクリプタ)
  • X>&Yは、「ディスクリプタXをディスクリプタYの複製として(=Yが参照する先を指すようにXを)リオープンする」と読みます。
  • リダイレクト処理は左から読みます(注:パイプがある場合、パイプを先に解釈)
  • >fileは1>fileの省略。<fileは0<fileの省略。
command >file 2>&1    #1をfileでreopen。2をfileでreopen
command 2>&1 >file    #2を端末(画面)でreopen。1をfileでreopen

リダイレクトとパイプ

読み方

  • リダイレクト処理は左から読みます(注:パイプがある場合、パイプを先に解釈)
command 2>&1 | command2         #2をパイプでreopen(1も2もパイプへ)
command >file 2>&1 | command2   #1をfileでreopen。2をfileでreopen
command 2>&1 >file | command2   #2をパイプでreopen。1をfileでreopen
  • パイプの実験先として、あまり害がないかつ入力が空だとすぐ分かるので、wcコマンドをよく使います
  • 出力を捨てたい時はリダイレクト先に /dev/null を使います

グルーピング

(command; command)     #子プロセスで実行。スペースはあってもなくても可。最後の;はあっても可
{ command; command; }  #カレントプロセス。前後のスペースと最後の;は必要。

ネットワーク管理

# よく使うオプション
netstat -anpt    #ソケットの状態を表示(grepでフィルタ)
netstat -rn      #ルーティングテーブルの状態を表示
ifconifg -a      #ネットワークインターフェースの状態を表示
arp -an          #ARP表の表示
dig -t MX @ns.ariel-networks.com ariel-networks.com   #DNSの動作確認

Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.