ちょっとひっかかったのでメモ。
実施環境:
Linux
[testuser@testhost ~]$ uname -a
Linux testhost 4.18.0-147.8.1.el8_1.x86_64 #1 SMP Thu Apr 9 13:49:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[testuser@testhost ~]$ echo $SHELL
/bin/bash
事象
以下のようなファイルがあるとします。
Linux
[root@testhost test]# ls -l test.txt
-rw-r--r--. 1 root root 3643 7月 17 08:47 test.txt
[root@testhost test]#
このファイルを cat コマンドに指定して適当なファイルにリダイレクトすると、内容がそのファイルにコピーされます。
Linux
[root@testhost test]# cat test.txt > test2.txt 2>&1
[root@testhost test]#
[root@testhost test]# ls -l test2.txt
-rw-r--r--. 1 root root 3643 7月 17 08:48 test2.txt
[root@testhost test]#
では、このリダイレクト先を同じファイルにするとどうなるでしょうか。
Linux
[root@testhost test]# cat test.txt > test.txt 2>&1
答えですが、指定したファイルが空となります。
Linux
[root@testhost test]# ls -l test.txt
-rw-r--r--. 1 root root 0 7月 17 08:48 test.txt
[root@testhost test]#
軽く調べたところ、 Linux ではリダイレクト(>
)を指定した際、コマンドの実行より前に「出力先の空ファイルを作成する/出力先ファイルを空にする」という処理を行うようです。
そのため、先の処理では
- test.txt を空にする
- test.txt の中身(空)を cat コマンドで標準出力に出力する
- 標準出力に出力した内容(空)を test.txt に書き込む
となるので、最終的に出力される test.txt は空ファイルとなってしまいました。
対処法としては、単にリダイレクト元のファイルとリダイレクト先のファイルを別々にすればよいです。
今回は cat コマンドを使用しましたが、他のコマンドでも同様のことは発生します。
ファイルの中身をコマンドで加工する際にやってしまいがちなので注意しましょう。