Weitere ähnliche Inhalte
Ähnlich wie シェルスクリプトを極める (20)
シェルスクリプトを極める
- 3. 仕事で使えるシェルスクリプト 3
fdfd を活用するを活用する
●
fd とはファイルディスクリプタの略
– オープンしたファイルの識別子
– 標準入力は 0
– 標準出力は 1
– 標準エラー出力は 2
– シェルではリダイレクト記号の前に数字
●
3> ファイル fd3 をファイルにリダイレクト
●
4< ファイル fd4 をファイルからリダイレクト
●
5<&- fd5 をクローズ
●
6>&7 fd7 を fd6 に複製 (fd6 を fd7 にリダイレクト
- 4. 仕事で使えるシェルスクリプト 4
● プロセスの出力同士を diff(1) で比較する
– 3<&0 で標準入力 (fd0) を fd3 に複製
– コマンド 1 の出力が fd3 に出力される
– /dev/fd/3 からの入力がコマンド 1 の出力
fdfd の活用方法①の活用方法①
$ diff <( コマンド 1 ) <( コマンド 2 )
$ コマンド 1 | ( コマンド 2 | diff /dev/fd/3 -) 3<&0
- 5. 仕事で使えるシェルスクリプト 5
fdfd の活用方法②の活用方法②
● パイプの途中のプロセスの終了コード
– コマンド 1 の $? を 1>&3 で fd3 に出力
– fd3 の内容を 3>&1 で ret1 に格納
$ exec 3>&1
ret1=`{ { コマンド 1; echo $? 1>&3; } | コマンド 2; } 3>&1`
ret2=$?
- 7. 仕事で使えるシェルスクリプト 7
fdfd の活用③の活用③
– exec 3<&0 で fd0 を fd3 に複製
– exec 0<<EOF でヒアドキュメントを fd0 として使用
– exec 0<&3 で複製した fd0 を復帰
– exec 3<&- で fd3 をクローズ
– パイプを使わないのでプロセスが生成されない
- 8. 仕事で使えるシェルスクリプト 8
fdfd の実装①の実装①
● コマンド > ファイル
– fd = open( ファイル , O_WRONLY|O_CREAT|O_TRUNC);
● ファイルを出力モードで open
– dup2(fd, 1);
● FD1( 標準出力 ) をクローズした後で fd を 1 に複製する
結果 fd が標準出力として使われる
- 9. 仕事で使えるシェルスクリプト 9
fdfd の実装②の実装②
● コマンド > ファイル 2>&1
– fd = open( ファイル , O_WRONLY|O_CREAT|O_TRUNC);
● ファイルを出力モードで open
– dup2(fd, 1);
●
FD1( 標準出力 ) をクローズした後で fd を FD1 に複製する
– dup2(1, 2);
●
FD2( 標準エラー出力 ) をクローズした後で FD1 を FD2 に複製する
結果 fd が標準出力、標準エラー出力として使われる
- 10. 仕事で使えるシェルスクリプト 10
fdfd の実装③の実装③
● コマンド 1| コマンド 2
– pipe(fd[]);
● パイプを生成
– コマンド 1 側 dup2(fd[1], 1);
● コマンド 1 の標準出力をパイプの出力側に複製する
– コマンド 2 側 dup2(fd[0], 0);
● コマンド 2 の標準入力をパイプの入力側に複製する
結果コマンド 1 の標準出力がコマンド 2 の標準入力になる
- 13. 仕事で使えるシェルスクリプト 13
ファイルのオーバーライドファイルのオーバーライド
● 元ファイルを書き替える
– ① でファイルが読み込みモードでオープンされる。
– ② でオープンされたファイルが削除される。
– ③ で新しい(別な)ファイルが書き込みモードでオープンされる。
● ① のファイルと③のファイルはたまたま同じファイル名なだけで、
inode が異なっているので OS からは別なファイル扱いなので正しく動作する。
$ コマンド < ファイル > ファイル # 絶対ダメ!
$ (rm ファイル ; コマンド > ファイル ) < ファイル
② ③ ①
- 15. 仕事で使えるシェルスクリプト 15
排他処理②排他処理②
● シェルスクリプトでの排他処理
– シンボリックリンクの作成は atomic
– PID をリンクする事でロックしたプロセスが特定できる
lockfile="/var/tmp/`basename ${0}`"
if ln -s $$ ${lockfile} 2> /dev/null
then
: # メイン処理を実行
else
echo "${0}: exist another instance" 1>&2
exit 255
fi
trap 'rm -f ${lockfile}; exit' 0 1 2 3 11 15
- 22. 仕事で使えるシェルスクリプト 22
exex を活用する⑤を活用する⑤
● パターンを指定した行置換処理
– 最初に発見したパターンを置換文字列に置換する
– s の後ろの連続した `//' は直前の正規表現(パターン)を示す
– `w!' で内容をファイルに出力する
$ /bin/ex -s ファイル << EOF
/ パターン /s// 置換文字列 /
w!
EOF
- 23. 仕事で使えるシェルスクリプト 23
exex を活用する⑥を活用する⑥
● ファイルから指定された行を削除する
– 元のファイル (basefile) には複数の行が含まれている
– 削除する行は別なファイル (target) に格納されている
– target ファイルには行番号が 1 行ずつ格納されている$ cat basefile
first line
second line
third line
:
:
$ cat target
2
3
5
:
:
- 24. 仕事で使えるシェルスクリプト 24
exex を活用する⑦を活用する⑦
● パターンを指定した行置換処理
– 削除済みの行を考慮する必要がある
→ 2 行目を削除すると今までの 3 行目が 2 行目になる
– ex で行を削除する
– awk で削除した行を考慮した行番号に対する行削除を出力
$ sort target |
awk '{ printf "%ddn", $1-(NR-1); } END { print "w!" }' |
ex -s basefile