2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

tarコマンドの順序を間違えてはいけない(戒め)

Last updated at Posted at 2024-11-06

/hoge/huga内のfileで始まるファイルをアーカイブ化し
/hoge/output.tarに出力する~といった場合に、
以下のようなコマンドを使ったところ困ったことになったのでめも

# これは誤りのコマンドなのでこの様式で実行するとひどいことになる。こうかいしませんね?
$ tar cvf /hoge/huga/file* /hoge/output.tar

tarコマンドのつかいかた

tarコマンドでアーカイブを作成する際には大体以下の様式でコマンドを実行する。

$ tar cvf <出力ファイル名> <アーカイブ対象ファイル ...>

で、冒頭の例示のように「このディレクトリ配下全部アーカイブしたいなぁ...」
と思って以下のように組み立てたとする。

$ tar cvf /hoge/output.tar /hoge/huga/file*

...まぁ/hoge/output.tarに理想通り出来上がる。

シェルコマンドでの「*(ワイルドカード)」

ところで、シェルコマンドにおける「*(ワイルドカード)」の扱いを振り返ってみよう。

$ ls /hoge/huga/
data1.txt data2.txt file1.txt file2.txt file3.txt

ファイルがこのようになっていた場合に以下のコマンドを入れてみる。

$ ls /hoge/huga/file*
file1.txt file2.txt file3.txt

なぜこのようになるか。

シェルはワイルドカードを含むパスを自動的に展開する。
例えば、/hoge/huga/file*は、/hoge/hugaディレクトリ内の
fileで始まるすべてのファイルパスを列挙する。

つまり以下のように入力されたものとして解釈する。

$ ls /hoge/huga/file1.txt /hoge/huga/file2.txt /hoge/huga/file3.txt

lsコマンドは引数に含まれているファイルの情報を出力するので
いくら指定されても問題ないってワケ。

試しに以下のコマンドで出力される内容を確認するとわかりやすい。

$ echo ~/*

ホームディレクトリに格納されているディレクトリ、ファイルが
先に示した例のように列挙される。

tarコマンドの指定順序を変えてみる

ここからが本題。先ほど組み立てたコマンドをもう一度。

$ tar cvf /hoge/output.tar /hoge/huga/file*

このファイル指定順序を反転して考えてみる。

$ tar cvf /hoge/huga/file* /hoge/output.tar

このコマンドを受け取ったシェルは、ワイルドカードを展開し以下のように解釈する。

$ tar cvf /hoge/huga/file1.txt /hoge/huga/file2.txt /hoge/huga/file3.txt /hoge/output.tar

まるで/hoge/huga/file1.txtを出力先として実行しているようになってしまう。

これを実行すると以下のように処理を進めていく。

  • /hoge/huga/file1.txt/hoge/huga/file2.txtをアーカイブとして書き込む。
  • /hoge/huga/file1.txt/hoge/huga/file3.txtを追加で書き込む。
  • /hoge/huga/file1.txt/hoge/output.tarを追加で書き込もうとするが、
    大体の場合当該ファイルは存在しないためエラーになる。
  • 前述のエラーによってコマンドが停止する。

実行結果としては/hoge/huga/file2.txt/hoge/huga/file3.txtが書き込まれた
かつての面影はない/hoge/huga/file1.txtが出来上がってしまう。
当然ながら/hoge/huga/file1.txtの内容はロストする上、/hoge/output.tarは作成されない。

さいごに

他のcpコマンドやmvコマンドなどと同じように「ここからここに(A→B)」のような書き方もあれば、
今回のtar コマンドのように「ここに、これらを(A←B[])」のような書き方(※追記あり)もあるので、
元データ、宛先など、それぞれのコマンドが必要としている情報を理解して利用していきたいものです。

2024/11/09追記

tarコマンドは-fオプションの引数を出力対象にするので、
以下のようにオプションの引数ですよと明示的にしておくと
間違いは減るかもしれません。
@shibapさんありがとうございます!

$ tar cv -f /hoge/output.tar /hoge/huga/file*

オプションはまとめて記載できてしまうので、
慣れてきた頃にまとめて打ち込むクセがついて
メモや手順書にそのまま書いてしまう事はあるかもしれません。

それを見た「そのコマンドをなんとなく使っている人」が他のコマンドと
同じノリで使うことでこのような過ちをする可能性はあるので、
記載者は「気をつけるオプションは分離するように」、
打鍵者は「分離されている意図、そのオプションの働き」を
押さえておくと良いのかなと思います。

参考

2
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?