改行コードについて

職場で改行コードについて質問を受けました。調べていたら結構大事な点があったのでメモ書きです。よくもこれまで大きなミスをしなかったな…と少々ビビッていたりして。

先ず、一般的な改行コードとしてLF, CRがあります。LFはUNIXで、CRはApple Macintoshで、MS WindowsではCR+LFという形で改行を認識しています。その詳細については次の通りです。

LF
Line Feed (改行)
ASCII Code : 0A(16), 10(10)
正規表現 : n
CR
Carriage Return (復帰)
ASCII Code : 0C(16), 13(10)
正規表現 : r

この文字コードをFTPで転送する場合、ASCIIモードで実行するとFTPクライアントの実行OSに合わせた形で転送が行われます。つまりMS WindowsからUNIXにASCIIモードでファイル転送(put)を行った場合には、UNIX上ではLFの前にあるCRを改行コードとして認識しないため文字化けが発生し得ます。…となると、異OS間でのファイル転送を行う場合にはバイナリモードでの転送を主とするか、受信側からgetでファイルを持ってくる方が安全かもしれませんね。

置換対象が改行コードの場合

今迄なるべくperlに近付かないようにsed, awkで文字列変換をしていたのですが、標記の件にてとうとうperlを用いてしまいました。例えばシーケンスデータの中でhogeが出現した時に改行をするという置換を行います。

sedだと改行コードnを置換先とするとnhogeとなってしまいます。

% sed 's/hoge/nhoge/g' filename
nhoge foo1 nhoge foo2 nhoge foo3

上と同じ処理をperlで実行してやると上手くいきました。

% perl -pe 's/hoge/nhoge/g' filename
 
hoge foo1
hoge foo2
hoge foo3

折角perlで処理するのでバックアップを取りながら文字列置換なんかをしてみたり。

% perl -pi.org -e 's/hoge/nhoge/g' filename
% ls filename*
filename      filename.org

最近では無いとは思いますけれどperlが入っていない環境では使えないのが玉に瑕です。

set user idとsticky bit

UNIXについてのテキストを作成している同僚から標記の話題が出たのでメモです。走り書きみたいな感じなのでワケが判らない文章になるかも。詳しく知りたい方はman chmodを実行する事をお勧めします。

UNIXファイルのパーミッションビットは通常下記の3つです。

r
Read permission
w
Write permission
x
Execute permission

しかしそれ以外にも下記のビットを立てる事があります。効果の程を一緒に記述しておきます。因みに下記の何れも最下ビットに立てられます。

s
Set-user-id or set-group-id
パーミッションを指定したファイル(ディレクトリ)のuser ID or group IDがファイル(ディレクトリ)実行時の実効ユーザ(グループ)となる。
t
The sticky bit
ownerにビットを立てる事によりread, writeに対して許可が一切必要なくなる。しかしremove, renameはwが立てられているユーザのみ可能。

owner固定のシェルスクリプトを作成する際にはsを利用した方が効果的な場合も出てくるでしょうし、tmpディレクトリのようなものを作成したい場合にはtを立てる事で実現可能となります。

awkで項目別に数値を集計する

仕事絡みでスクリプトを書いたので覚え書きです。

BEGIN {
i = 0;
}
 
{
if ( name[i] == $1 ) {
var[i] += $3;
}
else {
i += 1;
name[i] = $1;
description[i] = $2;
var[i] = $3;
}
}
 
END {
for ( j = 1; j <= i; j++ ) {
printf "%s,%s,%dn",name[j],description[j],var[j];
}
}

次のような感じで実行するとCSVからの集計が取れるので便利かも(スクリプトはtotal.awkで保存)。

% sort hoge.csv | awk -F , -f total.awk > total_hoge.csv

メールを強制的にリレーさせる

題名の付け方が非常に悪いのですが、要はドメイン参加していないUNIXサーバからメールを送信する場合の話です。

ドメインに参加していないサーバはMXレコードを参照できないのでDMZ内のSMTPにメールの送信を依頼しなければなりません。今回の場合はSendmailを用いて行いました。sendmail.cfの作成はm4で行っています。

例えばsendmail.mcをベースに生成する場合には、下記の一行を加えてm4 sendmail.mc >sendmail.cfを実行します。hogehoge.orgはSMTPサーバを示します。

define(`SMART_HOST',`hogehoge.org')

これで完了です。因みに今回はAIXの環境で行いました。参考にしたのはHowto configure AIX sendmail with .mc files and m4 (Ramses Smeyers’ Homepage)です。

AIXの場合のポイントは次の通りです。

mcファイルの位置
/usr/samples/tcpip/sendmail/cf/aixsample
mcファイルへ次の一行を追加する
include(`/usr/samples/tcpip/sendmail/m4/cf.m4')
m4の実行
m4 sendmail.mc >/etc/sendmail.cf

尚、AIXのSendmailのデーモンの起動・停止は次の様に行います。

# stopsrc -s sendmail
# startsrc -s sendmail -a "-bd -q30m"

補足

因みに反則技かもしれませんが、/etc/sendmail.cf中の下記の部分に直接ホスト名を書いても同様に動作しました。

# "Smart" relay host (may be null)
DShogehoge.org

AIXでBACKUP SCRIPTを作成(2)

AIXでBACKUP SCRIPTを作成の続編です。ORACLEの停止からバックアップ処理を行う場合には、ある程度sleepで間隔を取らないとエラーが出るようです。

当方は次のようなエラーが発生しました。しかもbackbyinodeのコマンドが残ったままになったりするので確りkillで殺してあげなければなりません。

backup: Date of this level 0 backup: Fri Oct  7 02:02:49 JST 2005
backup: Date of last level 0 backup: the epoch
backup: Backing up /dev/roracle-lv (/oracle) to /dev/rmt1.1
backup: File system still mounted, inconsistent data possible
backup: Mapping (Pass I) [regular files]
backup: Mapping (Pass II) [directories]
backup: estimated 61798693 1k blocks.
backup: Backing up (Pass III) [directories]
backup: Backing up (Pass IV) [regular files]
An error occurred when reading data from the device.
backup: Broken pipe
backup: Bad return code from backup: 1
backup: Can't open /dev/rmt1.1
Resource temporarily unavailable
backup: The backup command has ended abnormally.
backup: Can't open /dev/rmt1.1
Resource temporarily unavailable
backup: The backup command has ended abnormally.
backup: Can't open /dev/rmt1.1
Resource temporarily unavailable
backup: The backup command has ended abnormally.
/dev/rmt1: Resource temporarily unavailable

解消するためには環境によって左右されるのでしょうが、こんな感じでスクリプトを組んだら巧くいきました。

exec > $LOG 2>&1
su - orauser -c "lsnrctl stop"
if [ $? != 0 ];then
echo "Error : ORACLE LISTENER stop failed."
exit 1
fi
sleep 300
/usr/sbin/umount /oracle
if [ $? != 0 ];then
echo "Error : /oracle umount failed."
exit 1
fi
/usr/sbin/umount /hoge
if [ $? != 0 ];then
echo "Error : /hoge umount failed."
exit 1
fi
/usr/bin/mt -f/dev/rmt1 rewind
wait
/usr/sbin/backup -f/dev/rmt1.1 -0 /oracle
wait
/usr/sbin/backup -f/dev/rmt1.1 -0 /hoge
wait
/usr/bin/mt -f/dev/rmt1 offline

一部抜粋ですので中途半端なスクリプトですが、下記の要素を加えている事は判って頂けるのではないでしょうか。

  • ORACLEのシャットダウン処理が終わった時点で300秒待つ
  • テープにアクセスが行くコマンドについてはwaitで管理をする

慣れないOSを扱うのは難しいですね…(´Д⊂グスン

TeraTermとAIX

TeraTerm (Tera Term Home Page)からAIXに繋ぐ際の設定をメモ書き。

Terminal setup
ja_JPのデフォルト状態はShift JISでの表示っぽいので合わせる
Keyboard setup
全てチェックを外す
smitty使用時のファンクション入力
F4 = ESC + 4

因みにAIXのバージョンはAIX 5L V5.3です。

改行コードの一括置換

Windows上で編集したスクリプト等をUNIX上にアップロードしてからviで編集しようとした時に改行コードに^Mが付いている場合がありますよ。そんな時にはvi上で置換処理をしてしまいましょう。コマンドモードで下記の様に打ってリターンでOKです。

:%s/^M//g

因みに^MCTRL+Vを押した後CTRLを押しっ放しでMを入力します。

AIXでBACKUP SCRIPTを作成

最近AIXを触る機会が増えてきました。取りあえず忘れないようにバックアップスクリプトを覚え書きで残しておきます。

私が触っているのはAIX 5L V5.3です。AIXにはsmitとかいう管理ツールが付いていて会話式で色々作業ができるんですね。オマケにその作業時のコマンド履歴をsmit.scriptに残してくれるのでスクリプトを組むときにも楽チンです。

ただ少し癖があるな…と思ったのがデバイスの参照ですね…rmt0.1って最初なんだ?と思いましたが、要はno-rewindの事を表しているんだそうで。この辺をきっちり押えておかないと痛い目に合うな…と思いました。

因みに/をbackupコマンドから取得する時にはオプションとしてuを付けるんだそうです。/etc/dumpdateに履歴を残すとの事ですが…私にはイマイチどういう効果をもたらすモノなのか判りません。今後も要勉強ですね。

#!/bin/sh
 
date >>/foo/backup.log 2>&1
/usr/bin/mt -f /dev/rmt1 rewind
/usr/sbin/backup -f'/dev/rmt0.1' -0 -u /
/usr/sbin/backup -f'/dev/rmt0.1' -0 /usr
/usr/sbin/backup -f'/dev/rmt0.1' -0 /var
/usr/sbin/backup -f'/dev/rmt0.1' -0 /home
/usr/sbin/backup -f'/dev/rmt0.1' -0 /var/adm/ras/platform
/usr/sbin/backup -f'/dev/rmt0.1' -0 /opt
/usr/sbin/backup -f'/dev/rmt0.1' -0 /hoge1
/usr/sbin/backup -f'/dev/rmt0.1' -0 /hoge2
/usr/bin/mt -f /dev/rmt1 rewind
/usr/bin/mt -f /dev/rmt1 offline
date >>/foo/backup.log 2>&1

SunOSでのNFS設定

案件の中でSunOS 5.8(Solaris 8)をNFSのホストとして使うような設定をしました。あまりSunOSに触れる機会が今まで無かったのですが、このOSは独特ですね。折角手順が確定できたので覚え書きを残しておきます。

通常NFSの設定というと/etc/exportsを書いてhttp.equivを書いて…というような感じですが、SunOSの場合はexportsの代わり(?)に/etc/dfs/dfstabを編集するとの事。書式は次の通り。

share -F FileSystemType -o Option -d Description Resource

今回はNFSホストとしての定義をしたかったので下記の様に書いてみました。詳しくはmanを読んだ方が手っ取り早いかも。

share -F nfs -o rw -d "NFS for foo" /hoge

この後shareallというコマンドを実行してdfstabの内容を全て実行します。(『シェアする』というような云い方をするらしい。)

後はnfsdとmountdを起動(再起動)すればOK。何となく経験値から/usr/sbinを漁ってみたのですが見つからず。何と/usr/lib/nfsの下に居ました。何となくしっくり来ないですが…まあ良しとしましょう。

ここまで完了すれば後はクライアント側の設定のみ。/etc/fstabを弄ってマウント完了ですね。

因みにSunOS 5.8では/etc/fstabでは無くて/etc/vfstabでした。むむむ…(´・ω・`)