GNU/Linux >> Belajar Linux >  >> Linux

Keluar dari Karakter Tidak Dikenal Dari String Untuk -exec?

Saya memiliki perintah find yang menemukan file dan direktori tertentu. Perintah find itu kemudian menjalankan rsync dengan file dan direktori yang ditemukan sebelumnya sebagai sumber. Masalahnya adalah file dan direktori tersebut dapat memiliki semua jenis karakter seperti tanda kutip tunggal dan ganda belum lagi karakter ilegal dari Windows dll…

Bagaimana saya bisa secara dinamis keluar dari string untuk digunakan dalam rsync atau perintah lain?

Perintah ini bekerja dengan mengkodekan tanda kutip ganda untuk string sumber rsync, tetapi akan rusak jika string memiliki tanda kutip ganda di dalamnya.

find "/mnt/downloads/cache/" -depth -mindepth 1 \( \
-type f \! -exec fuser -s '{}' \; -o \
-type d \! -empty \) \
\( -exec echo rsync -i -dIWRpEAXogt --numeric-ids --inplace --dry-run '"{}"' "${POOL}" \; \)

keluaran yang dihasilkan:

rsync -i -dIWRpEAXogt --numeric-ids --inplace --dry-run "test/this " is an issue" /mnt/backing

Perintah yang berfungsi setelah info dalam jawaban diterapkan:

find "/mnt/downloads/cache/" -depth -mindepth 1 \( \
                             -type f \! -exec fuser -s {} \; -o \
                             -type d \! -empty \) \
                             \( -exec rsync -i -dIWRpEAXogt --remove-source-files-- "${POOL} \; \) \
                             -o \( -type d -empty -exec rm -d {} \; \)

Jawaban yang Diterima:

Masalah kutipan Anda berasal dari Anda mencoba memecahkan masalah yang tidak Anda miliki. Kebutuhan untuk mengutip argumen hanya berperan saat Anda berurusan dengan shell, dan jika find memanggil rsync secara langsung, tidak ada shell yang terlibat. Menggunakan output visual bukanlah cara yang baik untuk mengetahui apakah itu berhasil atau tidak karena Anda tidak dapat melihat di mana setiap argumen dimulai dan diakhiri.

Inilah yang saya maksud:

# touch "foo'\"bar"

# ls
foo'"bar

# find . -type f -exec stat {} \;
  File: ‘./foo'"bar’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 1659137     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1004/ phemmer)   Gid: ( 1004/ phemmer)
Access: 2017-12-09 13:21:28.742597483 -0500
Modify: 2017-12-09 13:21:28.742597483 -0500
Change: 2017-12-09 13:21:28.742597483 -0500
 Birth: -

Perhatikan bahwa saya tidak mengutip {} di arg ke stat .

Sekarang, perintah Anda akan menjadi sangat tidak berkinerja, karena Anda memanggil rsync untuk setiap file yang cocok. Ada 2 cara untuk menyelesaikan ini.

Seperti yang telah ditunjukkan orang lain, Anda dapat menggunakan pipa daftar file ke rsync di stdin:

# find . -type f -print0 | rsync --files-from=- -0 . dest/

# ls dest/
foo'"bar

Ini akan menggunakan byte nol sebagai pembatas nama file karena file tidak boleh berisi byte nol dalam namanya.

Terkait:Bagaimana cara memperbaiki kesalahan "Perangkat USB tidak dikenal membutuhkan lebih banyak daya daripada yang dapat dipasok Port"?

Jika Anda menggunakan GNU find , Anda memiliki metode lain untuk memanggil -exec , dan itu adalah -exec {} + . Dalam gaya ini find akan melewati lebih dari satu argumen pada suatu waktu. Namun semua argumen ditambahkan ke akhir perintah, bukan di tengah. Anda dapat mengatasinya dengan meneruskan argumen melalui shell kecil:

# find . -type f -exec sh -c 'rsync "[email protected]" dest/' {} +

# ls dest/
foo'"bar

Ini akan meneruskan daftar file ke sh yang kemudian akan menggantikannya dengan "[email protected]"


Linux
  1. Temukan -exec + Vs Temukan | Xargs:Yang Mana Yang Harus Dipilih?

  2. Perintah Untuk Mencetak Hanya 3 Karakter Terakhir Dari Sebuah String?

  3. Keluar Dari Temukan Jika -exec Gagal?

  1. Bagaimana cara menemukan path lengkap program C++ Linux dari dalam?

  2. Hapus semua karakter khusus dan huruf besar-kecil dari string di bash

  3. cara mencari direktori dari terminal di ubuntu

  1. Tes Shell Untuk Menemukan Pola Dalam String?

  2. Tr Analog Untuk Karakter Unicode?

  3. temukan perintah dari PID