Saya mencoba untuk tar.gz direktori dan menggunakan
tar -czf workspace.tar.gz *
Tar yang dihasilkan termasuk .svn
direktori dalam subdir tetapi BUKAN di direktori saat ini (karena *
diperluas hanya ke file 'terlihat' sebelum diteruskan ke tar
saya mencoba untuk
tar -czf workspace.tar.gz .
sebagai gantinya tetapi kemudian saya mendapatkan kesalahan karena '.' telah berubah saat membaca:
tar: ./workspace.tar.gz: file changed as we read it
Apakah ada trik agar *
cocok dengan semua file (termasuk dot-prefixed) dalam sebuah direktori?
(menggunakan bash di Linux SLES-11 (2.6.27.19)
linux
bash
design-patterns
tar
Micha
sumber
sumber
Jawaban:
Jangan membuat file tar di direktori yang Anda kemas:
melakukan trik, kecuali itu akan mengekstrak file di seluruh direktori saat ini ketika Anda membongkar. Lebih baik dilakukan:
cd .. tar -czf workspace.tar.gz workspace
atau, jika Anda tidak tahu nama direktori tempat Anda berada:
base=$(basename $PWD) cd .. tar -czf $base.tar.gz $base
(Ini mengasumsikan bahwa Anda tidak mengikuti symlink untuk sampai ke tempat Anda sekarang dan bahwa shell tidak mencoba menebak-nebak Anda dengan melompat ke belakang melalui symlink -
bash
tidak dapat dipercaya dalam hal ini. Jika Anda harus khawatir tentang itu, gunakancd -P ..
untuk melakukan direktori perubahan fisik. Bodoh bahwa ini bukan perilaku default dalam pandangan saya - membingungkan, setidaknya, bagi mereka yangcd ..
tidak pernah memiliki arti alternatif.)Satu komentar dalam diskusi mengatakan:
Bagian pertama dari komentar tidak masuk akal - jika file tar berisi direktori saat ini, itu tidak akan dibuat saat Anda mengekstrak file dari arsip itu karena, menurut definisi, direktori saat ini sudah ada (kecuali dalam keadaan yang sangat aneh ).
Bagian kedua dari komentar dapat ditangani dengan salah satu dari dua cara berikut:
/tmp
satunya : buat file di tempat lain - adalah satu kemungkinan lokasi - lalu pindahkan kembali ke lokasi asli setelah selesai.--exclude=workspace.tar.gz
opsi. String setelah=
adalah pola - contohnya adalah pola yang paling sederhana - pencocokan tepat. Anda mungkin perlu menentukan--exclude=./workspace.tar.gz
apakah Anda bekerja di direktori saat ini yang bertentangan dengan rekomendasi; Anda mungkin perlu menentukan--exclude=workspace/workspace.tar.gz
apakah Anda mengerjakan satu tingkat seperti yang disarankan. Jika Anda memiliki beberapa file tar untuk dikecualikan, gunakan '*
', seperti pada--exclude=./*.gz
.sumber
Jika Anda benar - benar tidak ingin memasukkan direktori teratas ke dalam tarball (dan biasanya itu ide yang buruk):
sumber
Acdrtux
, atau salah satu nama fungsi yang panjang. Surat fungsi tidak perlu diawali dengan-
, dan dapat digabungkan dengan opsi satu huruf lainnya.Ada beberapa langkah yang harus dilakukan:
*
dengan.
untuk menyertakan file tersembunyi juga.--exclude=workspace.tar.gz
dapat digunakan untuk mengecualikan arsip itu sendiri.tar: .: file changed as we read it
kesalahan saat arsip belum dibuat, pastikan arsip itu ada (misalnya menggunakantouch
), sehingga --exclude cocok dengan nama file arsip. (Tidak cocok jika file tidak ada)Hasil ini digabungkan dalam skrip berikut:
sumber
--verbose
, seperti:-czvf
.dalam direktori ingin kompres (direktori saat ini) coba ini:
sumber
.gz
file di direktori.Anda dapat memasukkan direktori tersembunyi dengan kembali ke direktori dan melakukan:
cd .. tar czf workspace.tar.gz workspace
Dengan asumsi direktori yang ingin Anda gzip bernama workspace.
sumber
tar -czf /path/to/where/you/do/have/permission/workspace.tar.gz workspace
-
sebelumczf
membuatnya bekerja. Jika tidak, saya mendapatkanCannot stat: No such file or directory
pesan kesalahan.Anda dapat memperbaiki
.
formulir dengan menggunakan--exclude
:sumber
Pembaruan: Saya menambahkan perbaikan untuk komentar OP.
memang akan mengubah direktori saat ini, tetapi mengapa tidak menempatkan file di tempat lain?
tar -czf somewhereelse/workspace.tar.gz . mv somewhereelse/workspace.tar.gz . # Update
sumber
Sebenarnya masalahnya ada pada opsi kompresi. Triknya adalah menyalurkan hasil tar ke kompresor alih-alih menggunakan opsi bawaan. Kebetulan itu juga dapat memberi Anda kompresi yang lebih baik, karena Anda dapat menyetel opsi kompresi tambahan.
Tar minimal:
Gunakan pipa ke kompresor pilihan Anda. Contoh ini verbose dan menggunakan xz dengan kompresi maksimum:
Solusi telah diuji pada Ubuntu 14.04 dan Cygwin pada Windows 7. Ini adalah jawaban wiki komunitas, jadi silakan mengedit jika Anda melihat kesalahan.
sumber
Masalah dengan sebagian besar solusi yang disediakan di sini adalah tar berisi
./
permintaan setiap entri. Jadi ini menghasilkan.
direktori saat membukanya melalui kompresor GUI. Jadi yang akhirnya saya lakukan adalah:ls -1A | xargs -d "\n" tar cfz my.tar.gz
Jika Anda sudah memiliki
my.tar.gz
direktori saat ini, Anda mungkin ingin menghapus ini:ls -1A | grep -v my.tar.gz | xargs -d "\n" tar cfz my.tar.gz
Sadarilah bahwa xargs memiliki batas tertentu (lihat
xargs --show-limits
). Jadi solusi ini tidak akan berhasil jika Anda mencoba membuat paket yang memiliki banyak entri (direktori dan file) pada direktori yang Anda coba tar.sumber
Pertanyaan yang bagus. Di ZSH Anda dapat menggunakan pengubah globbing
(D)
, yang merupakan singkatan dari "dotfiles". Membandingkan:ls $HOME/*
dan
ls $HOME/*(D)
Ini dengan benar mengecualikan entri direktori khusus
.
dan..
. Di Bash Anda dapat menggunakan.*
untuk menyertakan dotfiles secara eksplisit:ls $HOME/* $HOME/.*
Tapi itu termasuk
.
dan..
juga, jadi bukan itu yang Anda cari. Saya yakin ada cara untuk membuat*
dotfiles yang cocok di pesta juga.sumber
.??*
untuk mencocokkan semua file titik bukan.
dan..
. Itu tidak mendapatkan file titik karakter tunggal (seperti.a
). Untuk mendapatkannya juga, gunakan yang lebih rumit.[^.]*
.Solusi lain, dengan asumsi jumlah item di folder tidak besar:
(
ls -A
mencetak file normal dan tersembunyi tetapi bukan "." dan ".." sepertils -a
halnya.)sumber
Menentukan
.??*
akan menyertakan file "titik" dan direktori yang memiliki setidaknya 2 karakter setelah titik. Sisi negatifnya adalah tidak akan menyertakan file / direktori dengan karakter tunggal setelah titik, seperti.a
, jika ada.sumber
Jika ruang disk bukan masalah, ini juga bisa menjadi hal yang sangat mudah dilakukan:
sumber
Punya situasi yang sama sendiri. Saya pikir yang terbaik adalah membuat tar di tempat lain dan kemudian menggunakan -C untuk memberi tahu tar direktori dasar untuk file yang dikompresi. Contoh:
Dengan cara ini tidak perlu mengecualikan tarfile Anda sendiri. Seperti dicatat di komentar lain, -A akan menampilkan file tersembunyi.
sumber
10 tahun kemudian, Anda memiliki alternatif
tar
, diilustrasikan dengan Git 2.30 (Q1 2021), yang menggunakan "git archive
" ( man ) untuk menghasilkan rilis tarball alih - alih tar.(Anda tidak perlu Git 2.30 untuk menerapkan alternatif itu)
Lihat commit 4813277 (11 Okt 2020), dan commit 93e7031 (10 Okt 2020) oleh René Scharfe (
rscharfe
) .(Digabung oleh Junio C Hamano -
gitster
- di commit 63e5273 , 27 Okt 2020)Jadi, alih-alih:
Anda hanya dapat menggunakan Git:
Itu awalnya diusulkan karena, seperti dijelaskan di sini , beberapa platform eksotis mungkin memiliki distribusi tar lama dengan pilihan yang kurang.
sumber
Menggunakan
find
mungkin adalah cara termudah:find . -maxdepth 1 -exec tar zcvf workspace.tar.gz {} \+
find . -maxdepth 1
akan menemukan semua file / direktori / symlinks / etc di direktori saat ini dan menjalankan perintah yang ditentukan oleh-exec
. Di{}
dalam perintah berarti daftar file berada di sini dan\+
berarti bahwa perintah akan dijalankan sebagai:dari pada
sumber