経緯
サーバのメンテナンスをしていたら/etc/hostsの隣に/etc/hostseという謎のファイルがあることに気付く。
しかしネットで調べてもそんなファイルの情報は出てこず、疑念が深まる。
調査
中身を見てみると、/etc/hostsと微妙に違う部分あり。
「昔のファイルっぽい。でもバックアップ取った記憶ないな…」
なんかのデーモンが自動でバックアップを取ったのかなと思ったが、そもそもそんな設定を入れた記憶もありません。
ファイル更新日を見てもやはり昔のファイルのようです。
そもそもこのファイルを更新した時にどのようなコマンドを使ったっけ、ログを確認してみます。
sed -ie "s/192.168.1.1 /192.168.1.10/g" /etc/hosts #ipアドレスを変更
ふむ、sedコマンドを用いてipアドレスを置換変更しているのか。(知っている人ならここで気付く)
sedのバージョンは GNU sedの4.2.1。
ここで指定している-iオプションは上書き保存を指定しています。
-eは""内のスクリプトコマンドの指定です。これは省略可能ですが、複数スクリプトを指定する場合は全てのスクリプトに対して前置しなければならないため、慣例としてつけているようです。
-iで指定した上書きの段階でバックアップがとられているのかな?と思い、マニュアルを見てみます。
-i[SUFFIX]
--in-place[=SUFFIX]
This option specifies that files are to be edited in-place. GNU sed does this by creating a temporary file and sending output to this file rather than to the standard output.
<中略>
If no extension is supplied, the original file is overwritten without making a backup.
Because -i takes an optional argument, it should not be followed by other short options:
「SUFFIXの指定がなければそのまま上書きするが、-iの後は引数として認識するからオプションを続けたらだめだよ」
タイトル回収です。マニュアルの続きにはご丁寧に-iオプションの前置後置での挙動の変化が書かれていました。
つまり、-ieオプションの場合、
①-iで上書きが指定された。
②続くeは引数として、それを付与したファイルをバックアップとして保存した。
という挙動になっていたみたいです。だからeが付いていたのか…調べても出てこないわけだ
とはいえ、-eの直後にはスクリプトを記載しなければならず、-eiとも記載できないため、
そのまま上書きする場合は、「sed -i -e <スクリプト> <ファイル>」と個別に指定するのが正解のようです。
あえてバックアップを保存したい場合は
sed -i ".org" -e <スクリプト> <ファイル> #<ファイル名>.orgというバックアップを取って変更を上書き
といった使い方ができるということですね。
とはいえ、/etc内に似たファイル名があるとシステムの挙動がおかしくなる場合があるので、sedを使う場合は気をつけなければいけませんね。
結論
sedコマンドのオプションを一つにまとめてはいけない
参考
GNU sedマニュアル
https://www.gnu.org/software/sed/manual/sed.html