UNIXシェルスクリプト第10章 Part8
ディレクトリをコピーするシェルスクリプト dircopy
find . -depth -print |
findコマンドは -depthオプションを使うとディレクトリ階層の深い順に表示させる。
付けた場合 付けなかった場合
a/b/c/d/e a
a/b/c/d a/b
a/b/c a/b/c/
a/b/f/d/e a/b/c/d
a/b/f/d a/b/c/d/e
a/b/f a/b/f
a/b a/b/f/d
a/x/f/d/e a/b/f/d/e
a/x/f/d a/x
a/x/f/o a/x/f
a/x/f a/x/f/d
a/x/fo a/x/f/d/e
a/x a/x/f/o
a a/x/fo
-depthオプションをつける理由は、先に深い部分にアクセスして途中の読み込み不可や、検索不可といったエラーの要因を早めに見つけようとするため。
cpioを使ったコピーの場合、普通このオプションをつけた出力結果を渡す。
cpio -pdmu $TARGET 2>&1 |
cpioコマンドの基本オプションは3つある。
データを出力するときは-o、読み込んでくるときには-i、パス名を読み込んだコピーには-pを使う。
-dは必要に応じてディレクトリを作成する、-mはファイルの更新時刻を元のままのものを使う、-uは強制上書きという意味がある。
UNIXシェルスクリプト第10章 Part5
シェルアーカイブを作成するシェルスクリプト Shar
※シェルアーカイブというのはBSD4.4以降に作りこまれた機能の1つ。
少数のファイルをftpやmailで配布するのに便利なようにと作られたもの。
シェルスクリプトの中にファイルのリストと中身も入れて1つにしてしまうことで、
そのシェルスクリプトを実行すれば元のファイルを復元できるようにしている。
PCでいう自己展開形式のファイルを作成するようなもの。
使い方について
abcというディレクトリ下のファイルをシェルアーカイブにし、それを誰か別の人に渡したり別のディレクトリに移動させて展開するまで。
アーカイブを作成するには、
$ cd directory
$ Shar `find . -print` > directory.shar
このdirectory.sharファイルを人に渡したりメールで送ったりすればいい。
受け取った方は以下のようにすれば展開できる。
$ mkdir directory
$ mv directory.shar directory
$ cd directory
$ sh directory.shar
ただし、メールでそのまま渡された場合には$ sh directory.shar を行う前に。エディタを使ってこのファイルを開きメールのヘッダ部分を削除しておかなくてはならない。
なお、directory.sharという名称はどういう名前でも問題ない。
echo "#!/bin/sh"
echo "# This is a shell archive; to unpack:"
echo "# 1. Remove everything before the \"#!/bin/sh\"."
echo "# 2. Save the rest of the archive."
echo "# 3. Execute the archive by entering \"sh archive\"."
echo "#"
echo "# This archive contains the following files:"
echo "#"
作成するシェルアーカイブの先頭部分。
メッセージ中に日本語は書かないほうが良い。
for FILE
do
echo "# $FILE
done
このシェルアーカイブに含むファイルの名称をリストしている。
for FILE は for FILE in $* と同じ意味で、シェルスクリプトの引数全部が順番にこの変数に代入されていく。
sed 's/^X//'
sedコマンドで s/old/new とするとoldをnewで置き換える。
sed 's/^X//' >$FILE <<\EOF
XThis is a
XSample file.
EOF
<<\EOF とリダイレクトすると、次にEOFという文字が現れるまでをコマンドの入力として扱える。
\ があれば変数を値に変換することができ、なければ変換は行われない。
このような書き方をヒア・ドキュメントという。
UNIXシェルスクリプト第10章 Part3
プロセス名に対してシグナルを送るシェルスクリプト Kill
※killコマンドはプロセスIDに対してシグナルを送る。
プロセスIDは数字で表され、ユーザはpsコマンドを使って求めるプロセスが南蛮のプロセスIDで走っているのかを確認しなくてはならない。
プロセス番号ではなくプロセスの名前を指定してシグナルを送る。
実際にシグナルを送る前に確認応答が発生する。
-singnal
ここにはシグナルの番号やシグナルの種類を指定する。
kill(1)コマンドで指定できる形式でならどう書いても良い。
例えば -9 あるいは -KILL とすればそのプロセスに 9 番のシグナルを送る。
この指定がなかったらデフォルトとして 15 番を送る。
. SystemType.sh
ドットコマンド . で関数を定義したシェルスクリプトファイルを読みこませる必要がある。または、関数を直接書き込む必要がある。
ps $PS_OPTS
psコマンドはプロセスの情報を表示する。
sed '1d'
1行目を削除する。
grep "$NAME"
grepコマンドは指定した文字列を含む行を検索する。
grep -v "$0"
grepコマンドの -vオプションはパターンにマッチしなかった行を表示する。
exec < $PROCESS_LIST
while read LINE
do
IFS=$OLD_IFS
....
done
execコマンドは新しいプロセスを生成せずにコマンドを実行する。
execコマンドを使って標準入力を直接ファイルから読み込むことで、while文の入力がこのシェルスクリプト上で動作する。
while read LINE
do
IFS=$OLD_IFS
done < $PROCESS_LIST
とすると、このシェルスクリプトの子供のシェルとして動作する。
今回while文内でFOUNDという変数に値を代入し、while文を抜けてからその値によって処理を行っている。そのため、子供のシェルとして動作させてはいけない。
set $LINE
setコマンドはシェル変数を設定する。
setコマンドで位置パラメタをリセットすることにより、1番目のフィールドが$1、2番目のフィールドが$2というように順に代入される。
LINE=`echo "$LINE" | cut -c $COL-`
cutコマンドはファイルの各行から指定した範囲を表示する。
-cオプションは指定した部分を各文字を表示する。
$COL-のように指定すると、指定位置から行末までとなる。
set dummy $LINE
shift
PRONAME=$1
最初にdummyという文字列を意識的に入れておくことで、setコマンドにハイフンから始まる名前をオプションとして認識させないようにしている。
その後shiftで位置パラメタを1個ずらしてdummy部分を書く女子、コマンド名称をPRONAME変数に代入する。
"$PID $OWNER $PRONAME (y/n)? " </dev/tty
標準入力をPROCESS_LISTというファイルからリダイレクトしているために、このままでは標準入力を受け付けるところがない。
キーボードからの入力を可能にするには、このように/dev/ttyをリダイレクトしなくてはならない。