server-memo.net

tarコマンドの使い方

   

「tar」コマンドで、普段使いそうな内容をまとめています。

tarコマンドについて

tarコマンドを使用すると、複数のファイルをアーカイブ(まとめること)したり、アーカイブしたファイルを展開(元に戻すこと)することができます。

ファイルをアーカイブする際にデータを圧縮することもできるので、データのバックアップなどにも重宝します。

基本的な書式

普段使いそうな「tar」コマンドの使い方です

アーカイブ(無圧縮) tar cvf アーカイブ名.tar アーカイブ対象
アーカイブ(圧縮) tar czvf アーカイブ名.tar.gz アーカイブ対象
展開(無圧縮) tar xvf アーカイブ名.tar
解凍して展開 tar xzvf アーカイブ名.tar.gz
特定ファイルのみ取り出す tar xzvf アーカイブ名.tar.gz 取り出すファイル名(フルパス)
アーカイブ内容の確認 tar tzvf アーカイブ名.tar.gz

オプションの説明

上記コマンドで使用しているオプションの説明となります。

  • 「c」 新しいアーカイブを作成
  • 「x」 アーカイブからファイル・ディレクトリを展開
  • 「t」 アーカイブのリストを表示
  • 「f」 アーカイブ・展開するファイル・ディレクトリを指定
  • 「v」 詳細なログを表示(任意)
  • 「z」 gzipによる圧縮・解凍を実施

アーカイブ Tips

アーカイブを作成する際のちょっとしたTipsです。

複数のファイル・ディレクトリをアーカイブ

複数ファイル・ディレクトリをアーカイブする場合は、下記の通りアーカイブ対象のディレクトリやファイルを続けて指定します。

tar czvf アーカイブ名.tar.gz ファイル1 ファイル2 ファイル3
tar czvf アーカイブ名.tar.gz ディレクトリ1 ディレクトリ2 ディレクトリ3

ファイルとディレクトリを一緒にアーカイブすることもできます。

tar czvf アーカイブ名.tar.gz ディレクトリ1 ファイル1 ファイル2

実行例

複数のファイルとディレクトをアーカイブする実行例として、下記のファイルとディレクトリをアーカイブしていきます。

  • /etc/passwd
  • /etc/shadow
  • /etc/group
  • /home/test1(ディレクトリ)
# tar czvf user-data.tar.gz /etc/passwd /etc/shadow /etc/group /home/test1
tar: メンバ名から先頭の `/' を取り除きます
/etc/passwd
/etc/shadow
/etc/group
/home/test1/
/home/test1/.bash_logout
/home/test1/.bash_profile
/home/test1/.bashrc
/home/test1/.mozilla/
/home/test1/.mozilla/extensions/
/home/test1/.mozilla/plugins/

無事アーカイブすることができました。

アーカイブ対象をリストから読み込む

アーカイブする対象が多い場合などは、アーカイブ対象データを記述したリストファイルを用意し「--files-from」(または-T)オプションを使用してリストファイルを読み込ませてアーカイブすることもできます。

tar czvf アーカイブ名.tar.gz --files-from=リストファイル ディレクトリ

実行例

アーカイブ対象一覧を記述したファイルを作成します。(ファイル名は任意でok)

# cat archive-list
/etc/passwd
/etc/shadow
/etc/group
/home/test1

作成したファイルを「--files-from」オプションを使用して読み込んでアーカイブを行います。

# tar czvf user-data.tar.gz --files-from=archive-list
tar: メンバ名から先頭の `/' を取り除きます
/etc/passwd
/etc/shadow
/etc/group
/home/test1/
/home/test1/.bash_logout
/home/test1/.bash_profile
/home/test1/.bashrc
/home/test1/.mozilla/
/home/test1/.mozilla/extensions/
/home/test1/.mozilla/plugins/

リストに記述されたデータが、アーカイブされていることが確認できました。

一部を除いてアーカイブ

アーカイブする際に、アーカイブしたくないファイルやディレクトリがある場合「--exclude」オプションを使用することで、必要のないものを対象外とすることが出来ます。

tar czvf アーカイブ名.tar.gz --exclude=対象外データ ディレクトリ

対象外とするデータを指定する場合は、「*(ワイルドカード)」等の正規表現も使用できます。

対象外のデータが複数ある場合

アーカイブの対象外にしたいデータが多い場合は、その分「--exclude」を追加するか「--exclude-from」(または-W)オプションを使用して対象外のデータが記述されたファイルからリストを読み込むことができます。

「--exclude」複数パターン
tar czvf アーカイブ名.tar.gz --exclude=対象外データ --exclude=対象外データ2 ディレクトリ
「--exclude-from」パターン
tar czvf アーカイブ名.tar.gz --exclude-from=リストファイル ディレクトリ

実行例

テストように用意した「backup」というディレクトリを対象に「--exclude」と「--exclude-from」オプションを使用した実行例として挙げていきます。

検証用データ
$ tree --charset=C backup
backup
|-- backup_01
|-- backup_02
|-- backup_03
|-- backup_04
|-- backup_05
`-- old
    |-- backup_06
    |-- backup_07
    |-- backup_08
    |-- backup_09
    `-- backup_10

1 directory, 10 files
「--exclude」実行例 oldディレクトリをアーカイブから除外

「backup」ディレクトリをアーカイブする際に、「old」ディレクトリを除外してアーカイブを行っていきます。

$ tar czvf backup.tar.gz --exclude=old backup
backup/
backup/backup_01
backup/backup_02
backup/backup_03
backup/backup_04
backup/backup_05

実行結果をみると「old」ディレクトリが除外されていることがわかります。

「--exclude」実行例 oldディレクトリ内の「backup_06」から「backup_08」を除外

正規表現も使用可能できます。

$ tar czvf backup.tar.gz --exclude=old/backup_0[6-8] backup
backup/
backup/old/
backup/old/backup_09
backup/old/backup_10
backup/backup_01
backup/backup_02
backup/backup_03
backup/backup_04
backup/backup_05
「--exclude-from」実行例

アーカイブから除外したいデータを記述したファイル「exclude-list」を下記の内容で作成します。
(ファイル名はなんでもokです)

$ cat exclude-list
backup_03
backup_04
backup_05
old/backup_0[7-9]
old/backup_10

「-exclude-from」オプションを使用して、除外したいデータをリストから読み取りアーカイブを行います。

$ tar czvf backup.tar.gz --exclude-from=exclude-list backup
backup/
backup/old/
backup/old/backup_06
backup/backup_01
backup/backup_02

リストに記述されたデータはアーカイブされていないことが確認できます。

findの検索結果をtarでアーカイブ

「find」コマンドでデータを検索して、該当したデータを「tar」でアーカイブする方法です。

find / -name "データ名" -print0 | tar -cvz -T - --null -f アーカイブ名.tar.gz

findとtarの組み合わせ時はxargsを使わない理由

「find」の検索結果を引数として「xargs」コマンドに渡して、何か処理を実行するという方法が良く紹介されていますが、「tar」でアーカイブする場合は「xargs」コマンドを使用すると、アーカイブ対象ファイルが多い場合、全てのファイルをアーカイブすることが出来ない場合があります。

これは、検索結果が「xargs」コマンドのバッファ制限を超えた場合、バッファの範囲内になるようにコマンドを分けて実行するため、「tar」が複数回処理されて最後の分のみがアーカイブされてしまうため、この現象が発生してしまうのです。

参考サイト

http://diaryruru.blog.fc2.com/blog-entry-32.html

実行例

.logという拡張子のファイルを「find」で検索して「tar」でアーカイブした例です。

# find / -name "*.log" -print0 | tar -cvz -T - --null -f logs.tar.gz
tar: -: file name read contains nul character
tar: Removing leading `/' from member names
/var/log/audit/audit.log
/var/log/tuned/tuned.log
/var/log/anaconda/anaconda.log
/var/log/anaconda/anaconda.program.log
/var/log/anaconda/anaconda.packaging.log
/var/log/anaconda/anaconda.storage.log
/var/log/anaconda/anaconda.ifcfg.log
/var/log/anaconda/ks-script-_l6IQg.log
/var/log/anaconda/ks-script-tOFjbG.log
/var/log/wpa_supplicant.log
/var/log/yum.log
/var/log/boot.log
/var/log/clamav/clamd.log
/var/log/clamav/freshclam.log
/var/log/httpd/server-memo.log
/usr/lib/rpm/rpm.log
/usr/share/doc/libjpeg-turbo-1.2.90/change.log

find + xargs + tar の失敗例

テスト用に10,000個ファイルを作成して「xargs」を使わないパターンと、使うパターンでアーカイブ結果を比較してみます。

テスト用ファイル作成

検証用に10,000個のファイルを作成します。

$ seq -f "%05g_file" 10000 | xargs touch
$ ls | wc -l
10000
「xargs」を使用しないでアーカイブ

まず、「xargs」コマンドを使用せずにアーカイブを行います。

アーカイブされたファイルを表示させて「wc -l」で行数をカウントしてみると、10,000ファイルアーカイブ確認されることが確認できました。

$ find ./data/ -name "*_file" -print0 | tar -czv -T - --null -f tar-test.tar.gz
$ tar tvzf tar-test.tar.gz | wc -l
10000
「xargs」を使用してアーカイブ

次に「xargs」コマンドを使用してアーカイブを行ってみます。

こちらはアーカイブされているファイルの数を「wc -l」でカウントしてみると2,720と表示されて、一部のファイルだけしかアーカイブされていないことが確認できます。

$ find ./data/ -name "*_file" | xargs tar cfzv tar-xargs.tar.gz
$ tar tvzf tar-xargs.tar.gz | wc -l
2720

このように、ファイルの数が多い場合「xargs」コマンドを使用すると、一部のデータしかアーカイブされないことが確認できました。

シンボリックリンク先を実体としてアーカイブ

シンボリックリンクを含んだデータをアーカイブする場合、通常の方法ではシンボリックリンクの情報だけがアーカイブされて、リンク先のデータはアーカイブされません。

リンク先のデータもアーカイブしたい場合は、「h」オプションを使用することでリンク先の実データをアーカイブすることができます。

tar czhvf アーカイブ名.tar.gz アーカイブ先

実行例

シンボリックリンクである「/etc/http/logs」を、「h」オプション「あり」「なし」の2通りでアーカイブ結果を比べていきます。

アーカイブ対象

「/etc/http/logs」がシンボリックリンクであることを確認しておきます。

# ls -l /etc/httpd/
合計 8
drwxr-xr-x. 2 root root   56  2月 10 21:06 conf
drwxr-xr-x. 2 root root 4096  2月 10 21:11 conf.d
drwxr-xr-x. 2 root root 4096  2月 10 21:06 conf.modules.d
lrwxrwxrwx  1 root root   19  2月 10 21:06 logs -> ../../var/log/httpd
lrwxrwxrwx  1 root root   29  2月 10 21:06 modules -> ../../usr/lib64/httpd/modules
lrwxrwxrwx  1 root root   10  2月 10 21:06 run -> /run/httpd
「h」オプションなし

まずは「h」オプションなしでアーカイブしていきます。

# tar czvf httpd.tar.gz /etc/httpd/logs/

アーカイブされたデータを展開します。

# tar xzfv httpd.tar.gz
etc/httpd/logs

展開されたデータはシンボリックリンクであることが確認できます。

# ls -l etc/httpd/
合計 0
lrwxrwxrwx 1 root root 19  2月 10 21:06 logs -> ../../var/log/httpd

「file」コマンドで確認してみると壊れたシンボリックリンク(broken symbolic link)であること表示されます…

# file etc/httpd/logs
etc/httpd/logs: broken symbolic link to `../../var/log/httpd'

「cd」コマンドでディレクトリを移動してみようすとると、ディレクトリが無いと怒られ、実際のデータはアーカイブされてい無いことが分かります。

# cd etc/httpd/logs
-bash: cd: etc/httpd/logs: そのようなファイルやディレクトリはありません
「h」オプションあり

次に「h」オプションを使用してアーカイブしていきます。

# tar czhf httd.tar.gz /etc/httpd/logs/

アーカイブされたデータの展開時のログを確認すると、今度はシンボリックリンク先の実データがアーカイブされている事がわかります。

# tar xzvf httd.tar.gz
etc/httpd/logs/
etc/httpd/logs/server-memo.log-20161031
etc/httpd/logs/server-memo.log-20161101
etc/httpd/logs/access_log-20161106
etc/httpd/logs/error_log-20161106
etc/httpd/logs/server-memo.log-20161106
etc/httpd/logs/server-memo.log
etc/httpd/logs/access_log-20161114
etc/httpd/logs/access_log
etc/httpd/logs/error_log-20161114
etc/httpd/logs/error_log

実際に展開されたデータを確認すると、実際のディレクトリとして「logs」が存在していることが分かります。

# ls -l etc/httpd/
合計 4
drwx------ 2 root root 4096  2月 14 17:15 logs

「logs」ディレクトリの中身も確認すると、ログファイルが実際のデータとしてアーカイブされていたことが確認できます。

# ls -l etc/httpd/logs/
合計 29236
-rw-r--r-- 1 apache apache          0 11月 14 07:11 access_log
-rw-r--r-- 1 apache apache     241574 11月  6 08:26 access_log-20161106
-rw-r--r-- 1 apache apache      18882 11月 10 14:09 access_log-20161114
-rw-r--r-- 1 apache apache         0 11月 14 07:11 error_log
-rw-r--r-- 1 apache apache      10488 11月  6 08:26 error_log-20161106
-rw-r--r-- 1 apache apache      6913 11月 10 14:09 error_log-20161114
-rw-r--r-- 1 apache apache        0 11月  6 08:26 server-memo.log
-rw-r--r-- 1 apache apache   7488057 10月 31 04:26 server-memo.log-20161031
-rw-r--r-- 1 apache apache  15599403 11月  1 03:42 server-memo.log-20161101
-rw-r--r-- 1 apache apache   6559587 11月  1 14:40 server-memo.log-20161106

展開 Tips

アーカイブされたデータを展開する際のTipsです。

一部のファイル・ディレクトリだけを取り出す

アーカイブされたデータから一部のファイルやディレクトリを取り出す場合、取り出したいデータを指定することで、そのデータだけを取り出すことができます。

tar xzvf ファイル名.tar.gz 該当ファイル・ディレクトリ名

取り出すデータを指定する場合は、パスも含めて指定する必要があります。

実行例

下記内容のアーカイブデータから「backup_01」というファイルだけを取り出していきます。

アーカイブ内容
$ tar tzvf backup.tar.gz
drwxrwxr-x tamohiko/tamohiko 0 2017-02-11 00:28 backup/
drwxrwxr-x tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/backup_06
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/backup_07
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/backup_08
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/backup_09
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/backup_10
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/backup_01
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/backup_02
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/backup_03
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/backup_04
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/backup_05
-rw-rw-r-- tamohiko/tamohiko 0 2017-02-11 00:28 backup/test.txt
ファイルの取り出し

アーカイブから「backup_01」ファイルだけを取り出します。

$ tar xzvf backup.tar.gz  backup/backup_01
backup/backup_01

「backup_01」ファイルだけ取り出されたことが確認できます。

$ ls -l backup
合計 0
-rw-rw-r-- 1 tamohiko tamohiko 0  1月  3 18:55 backup_01

展開場所を指定

「-C」(大文字のC)オプションを使用することで、アーカイブを展開する場所を指定することが出来ます。

tar xzvf ファイル名.tar.gz -C 展開したいディレクトリを指定

実行例

アーカイブデータ「backup.tar.gz」の展開先として「/homo/tamohiko/test」ディレクトリを指定します。

$ tar xzf backup.tar.gz -C /home/tamohiko/test

展開先として指定したディレクトリにデータが展開されていることが確認できます。

$ ls -l /home/tamohiko/test
合計 0
drwxrwxr-x 3 tamohiko tamohiko 111  2月 11 00:28 backup

アーカイブ操作 Tips

アーカイブデータを操作するためのTipsです。

ファイルの中身を確認する方法

「t」オプションを使用することで、アーカイブされているデータを展開せずに内容を確認することが出来ます。

tar tf ファイル名.tar.gz

「v」オプションも合わせて指定すると、さらに詳しい情報が表示されます。

実行例

「v」オプションなし

「v」オプションを付けない場合は下記のように、アーカイブの中身が表示されます。

$ tar tf backup.tar.gz
backup/
backup/old/
backup/old/backup_06
backup/old/backup_07
backup/old/backup_08
backup/old/backup_09
backup/old/backup_10
backup/backup_01
backup/backup_02
backup/backup_03
backup/backup_04
backup/backup_05
backup/test.txt
「v」オプションあり

「v」オプションを使用すると、アーカイブされているデータの詳細な情報も表示させることが出来ます。

$ tar tvf backup.tar.gz
drwxrwxr-x tamohiko/tamohiko 0 2017-02-11 00:28 backup/
drwxrwxr-x tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/backup_06
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/backup_07
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/backup_08
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/backup_09
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/old/backup_10
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/backup_01
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/backup_02
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/backup_03
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/backup_04
-rw-rw-r-- tamohiko/tamohiko 0 2017-01-03 18:55 backup/backup_05
-rw-rw-r-- tamohiko/tamohiko 0 2017-02-11 00:28 backup/test.txt

アーカイブされたファイルの中身を表示

「O」(大文字のO)オプションを使用することで、アーカイブされたファイルの内容を展開せずに表示させることができます。

tar xzOf アーカイブ名.tar.gz ファイル名

実行例

アーカイブされていている「test.txt」の内容を表示させてみます。
(このファイルには「test data」と記述されています)

$ tar xzOf backup.tar.gz backup/test.txt
test data

「test.txt」の内容を表示させることが出来ました。

 - コマンド