Jika saya ingin membuat isi yang file2
sesuai dengan isi file1
, saya jelas bisa langsung lari cp file1 file2
.
Namun, jika saya ingin melestarikan segala sesuatu tentang file2
kecuali isi-pemilik, perizinan, atribut diperpanjang, ACL, hard link, dll, dll, maka saya tidak akan ingin menjalankan cp
. * Dalam hal ini saya hanya ingin celepuk yang isi file1
ke dalam file2
.
Sepertinya yang berikut akan melakukannya:
< file1 > file2
Tapi itu tidak berhasil. file2
dipotong menjadi tidak ada dan tidak ditulis untuk. Namun,
cat < file1 > file2
tidak bekerja.
Itu mengejutkan saya bahwa versi pertama tidak berfungsi.
Apakah versi kedua UUOC? Apakah ada cara untuk melakukan ini tanpa menggunakan perintah, hanya dengan menggunakan pengalihan?
Catatan: Saya sadar bahwa UUOC lebih merupakan titik pedantic daripada anti-pola yang sebenarnya.
* Sebagai tniles09 ditemukan , cp
akan sebenarnya bekerja dalam kasus ini.
sumber
< file1 > file2
melakukan apa yang Anda inginkan tergantung pada shell.<
...file1
tidak ada atau tidak dapat dibaca dan Anda membukanya dengan<
sebelum>
output dibuka, dan kemudian mempertimbangkan apa yang terjadi ketika Anda mengizinkancat
untuk mencoba membukanya.cat
(secara default), pada dasarnya menjalankan perintah kedua. Lihat jawaban Stéphane Chazelas di bawah ini untuk lebih dari itu daripada cocok dalam komentar.Jawaban:
cat < file1 > file2
bukan UUOC. Klasik,<
dan>
lakukan pengalihan yang sesuai dengan duplikasi file deskriptor di tingkat sistem. Duplikasi file deskriptor sendiri tidak melakukan apa-apa (well,>
redirections terbuka denganO_TRUNC
, jadi untuk menjadi akurat, redirection output memang memotong file output). Jangan biarkan<
>
simbol membingungkan Anda. Pengalihan tidak memindahkan data — mereka menetapkan deskriptor file ke deskriptor file lainnya.Dalam hal ini Anda membuka
file1
dan menetapkan deskriptor file tersebut ke deskriptor file0
(<file1
==0<file1
) danfile2
dan menetapkan deskriptor file tersebut ke deskriptor file1
(>file2
==1>file2
).Sekarang setelah Anda memiliki dua deskriptor file, Anda perlu proses untuk menyekop data di antara keduanya — dan itulah gunanya
cat
.sumber
Bukan, karena seperti yang telah ditunjukkan orang lain, perilaku yang dipermasalahkan bergantung pada shell. Seperti yang telah Anda (OP) tunjukkan, ini agak terlalu menyolok , bahkan mungkin lucu? , semacam topik.
Namun, pada sistem GNU, premis awal Anda memiliki solusi lain yang tersedia:
cp --no-preserve=all file1 file2
. Coba ini, saya pikir itu akan memuaskan situasi yang Anda gambarkan (misalnya memodifikasi kontenfile2
sambil tidak mengubah atributnya).contoh :
PEMBARUAN Sebenarnya, saya hanya memperhatikan bahwa sistem saya
cp
dengan sendirinya tampaknya mempertahankan atribut kecuali-a
atau-p
ditentukan. Saya menggunakan bash shell dan GNU coreutils. Saya kira Anda belajar sesuatu yang baru setiap hari ...Hasil pengujian (menurut Wildcard) termasuk tautan keras dan izin berbeda:
sumber
Dalam
zsh
, shell di mana< file1 > file2
berfungsi, shell tidak memanggilcat
.Untuk baris perintah yang hanya terdiri dari pengalihan dan tanpa perintah atau penugasan,
zsh
panggil$NULLCMD
(cat
secara default) kecuali pengalihan hanya adalah yang<
dalam hal ini$READNULLCMD
(pager
secara default) dipanggil sebagai gantinya. (itu kecualizsh
ada dalamsh
ataucsh
emulasi dalam hal ini berperilaku seperti cangkang yang ditiru).Begitu:
sebenarnya sama dengan
dan
sama dengan
sumber
tidak berfungsi karena tidak ada perintah di sana; tidak ada proses. Shell membuka / membuat file dan mengatur pengalihan (artinya deskriptor file yang mereferensikan file ini ditanam sebagai 0 dan 1: input standar dan output standar). Tetapi tidak ada yang bisa dilakukan mengeksekusi loop untuk membaca dari input standar dan menulis ke output standar.
zsh
membuat ini bekerja dengan mengganti perintah yang dapat dikonfigurasi pengguna dalam kasus "perintah nol" ini. Perintah tidak terlihat di baris perintah, tetapi masih ada di sana. Suatu proses dibuat untuk itu dan bekerja dengan cara yang sama.NULLCMD
secaracat
default, jadi< from > to
sebenarnya berarticat < from > to
dalamzsh
, kecualiNULLCMD
diatur ke sesuatu yang lain; ini adalah perintah "kucing implisit"."Penggunaan kucing yang tidak berguna" terjadi ketika
cat
digunakan sebagai perantara untuk membaca dari file dan mengumpankan data ke proses lain, yang deskriptor file-nya hanya dapat dihubungkan ke file asli.Jika
cat
dilepas dari situasi, sehingga perintah yang tersisa masih dapat melakukan tugas yang sama, itu tidak berguna. Jika tidak dilepas, maka itu tidak berguna.A
cat
yang bisa diganti bukan hal yang sama. Misalnya alih-alih yangcat > file
bisa kita gunakanvi file
untuk membuat file. Itu tidak dihitung sebagai penghapusancat
, saat menggunakan apa pun yang tersisa untuk mencapai tugas yang sama.Jika
cat
adalah satu - satunya perintah dalam pipa, maka tentu saja itu tidak dapat dihapus; tidak ada pengaturan ulang apa pun yang tersisa akan melakukan pekerjaan yang setara.Beberapa skrip shell digunakan
cat
karena mereka pikir itu memungkinkan mereka memindahkan operan input lebih dekat ke sisi kiri baris perintah. Namun, pengalihan bisa di mana saja di baris perintah:sumber
f -
tar.tar xf -
hanyatar x
.cat
ia terlibat dalam pembuatan file? Jawaban dengan jelas mengatakan bahwa shell melakukan ini. Masalah apa> file
yang Anda maksudkan? Saya sering menggunakannya sendiri untuk memotong file yang sudah ada hingga nol panjang atau memastikan ada. Pertanyaan ini tentang mengapa< from > to
tidak berfungsicat < from > to
, dan UUoC, bukan "tolong beri saya alasan mengapacat
bukan pengganti yang baik untukcp
".tar
adalah pengarsipan tape . Banyaktar
implementasi masih bekerja dengan perangkat rekaman pertama secara default.< file1 > file2
Tampaknya tergantung pada shell, pada zsh berfungsi, pada bash tidak.sunting: pernyataan salah dihapus
sumber
cp -a
mempertahankan atribut file1 dan menimpa atribut file2. Berlawanan dengan perilaku yang diinginkan. Ditambah lagi, saya tidak bisa mengatakan dengan melihat halaman manual apa yang akan terjadi dengan tautan keras, tetapi saya pikir aman untuk mengatakan bahwa tautan keras file2 tidak akan disimpan.Selain semua jawaban yang baik, Anda dapat menghindari UUOC dengan simulasi sebuah
cat
:Perintah-perintah ini tidak menyalin file meta data, seperti biasa
cp
.sumber
cat
. Di sini Anda perlu perintah untuk mendorong data antara dua file deskriptor dancat
merupakan salah satu yang terbaik untuk itu. Lihat jugapv
yang dapat digunakansplice()
di Linux untuk fifos, (meskipun tidakfadvise(POSIX_FADV_SEQUENTIAL)
seperti GNUcat
).dd
perintah untuk file biner tampaknya baik ... atau akancat
bekerja sama dengan baik untuk file biner?cat
juga berfungsi untuk file biner (Unix umumnya tidak membedakan; namun, beberapa alat secara khusus bekerja baris demi baris, seperti awk, grep, wc, ... POSIX juga mendefinisikan panjang garis minimum terbesar, jadi secara teori alat yang berorientasi garis mungkin menolak berurusan dengan saluran yang terlalu besar.)sed '' < file1 > file2
;-)Jika berhasil, jangan memperbaikinya.
Saya akan menggunakan
dan tidak memusingkan PC semantik.
sumber