(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

catコマンドにてinput file is output fileとエラーが出る際のポイント

スポンサーリンク

はじめに

入力ファイルと出力ファイルを同じにするコマンドは避けるべきであり、例えば実際に押下した場合は以下のメッセージが表示されてcatコマンドに失敗します。

$ cat abc.txt >> abc.txt
cat: abc.txt: input file is output file
$ cat abc.txt > abc.txt
cat: abc.txt: input file is output file

ただし、上書きである>か追記である >>では結果が大きく変わります。

本記事ではそれらの違いについて簡単に説明します。

catコマンドのバージョン
$ cat --version
cat (GNU coreutils) 8.22
...

> : ファイル初期化 >> : ファイル無変更

abc.txt に abc という文字列を記載します。

# echo abc > abc.txt
# cat abc.txt
abc

この状態でリダイレクトを>とするとファイルが空になります。

# cat abc.txt > abc.txt
cat: abc.txt: input file is output file
# cat abc.txt

リダイレクトを>>とするとファイルは変更されません。

# echo abc > abc.txt
# cat abc.txt
abc
# cat abc.txt >> abc.txt
cat: abc.txt: input file is output file
# cat abc.txt
abc

再度書き込まれているわけではなく、ファイルが更新された日付を見ても書き込まれていないのが分かります。

これらの違いは > abc.txt とすることで abc.txt の初期化が入ることが原因です。
その後の catコマンドで エラーが発生して書き込みが失敗するのはリダイレクト方式の違いに関わらず同様です。

試しにstraceコマンド*1で詳細を確認すると、どちらもNo such file or directoryでエラーとなっています。

$ strace cat abc.txt > abc.txt
...
open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "cat: ", 5cat: )                    = 5
write(2, "abc.txt: input file is output fi"..., 34abc.txt: input file is output file) = 34
write(2, "\n", 1
)                       = 1
close(3)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++
$ strace cat abc.txt >> abc.txt
...
open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "cat: ", 5cat: )                    = 5
write(2, "abc.txt: input file is output fi"..., 34abc.txt: input file is output file) = 34
write(2, "\n", 1
)                       = 1
close(3)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++

終わりに

「input file is output file」というエラーメッセージはcatコマンドによる書き込みに失敗したというだけで「 > ファイル名」によってファイル名が初期化されてしまうことは成功しています。

お気をつけください。

*1:strace : システムコールやシグナルをトレースするコマンド