giải thích cp --no-target-thư mục


10

Câu hỏi: Tôi cần một ví dụ đơn giản về cách sử dụng cp --no-target-directory.

Tôi có một số khó khăn trong việc hiểu cp --no-target-directory. Tôi thực sự hiểu lời giải thích chomv --no-target-directory , nhưng tôi thực sự không thể tưởng tượng ra cách sử dụng nó cho cp.

Ví dụ, khi lệnh mv /tmp/source /tmp/destthành công, không có gì đảm bảo /tmp/sourceđược đổi tên thành /tmp/dest: /tmp/dest/sourcethay vào đó, nó có thể được đổi tên thành , nếu một số quy trình khác được tạo /tmp/destnhư một thư mục. Tuy nhiên, nếu mv -T /tmp/source /tmp/destthành công, không có câu hỏi nào /tmp/source was renamed to/ tmp / Dest`. ( nguồn )

Câu trả lời:


15

Theo mặc định, cpkiểm tra nếu đối số cuối cùng của nó là một thư mục hiện có. Nếu điều này xảy ra, cptạo một liên kết bên trong thư mục đó, với tên cơ sở của nguồn. Đó là, đưa ra lệnh

cp foo/bar wibble

nếu wibblelà một thư mục hiện có thì cpsao chép nguồn vào wibble/bar. Nếu wibblekhông tồn tại thì cpliên kết nguồn tới wibble.

Nếu bạn muốn chắc chắn rằng bản sao luôn luôn wibble, thì bạn có thể chỉ định tùy chọn --no-target-directory(bí danh -T). Bằng cách đó, nếu cpthành công, bạn có thể chắc chắn rằng bản sao được gọi wibble. Nếu wibbleđã tồn tại như một thư mục, thì cpsẽ thất bại.

Ở dạng bảng:

The target is …             Without -T               With -T
existing directory          copy in the directory    error
existing file (not dir)     overwrite                overwrite
does not exist              create                   create

Sự khác biệt duy nhất là với -T, trong trường hợp đích là một thư mục hiện có, lệnh sẽ trả về một lỗi. Điều này hữu ích khi bạn mong muốn thư mục không tồn tại: bạn nhận được thông báo lỗi thay vì điều gì đó không dự đoán được xảy ra.

Điều tương tự áp dụng cho mvln. Nếu mục tiêu là một thư mục hiện có, với -T, chúng báo hiệu một lỗi thay vì âm thầm làm điều gì đó khác đi.

Với cp, có một trường hợp khác. Nếu bạn thực hiện một bản sao đệ quy và nguồn là một thư mục, sau đó cp -Tsao chép nội dung của nguồn vào đích, thay vì sao chép chính nguồn đó. Đó là, đã cho

$ tree source destination 
source
└── foo
destination
└── bar

sau đó

$ cp -rv source destination
`source' -> `destination/source'
`source/foo' -> `destination/source/foo'

trong khi

% cp -rvT source destination
`source/foo' -> `destination/foo'

8

Bạn sẽ sử dụng --no-target-directorynếu bạn không muốn một thư mục nguồn được sao chép bên dưới một thư mục đích hiện có, bạn muốn thư mục nguồn được sao chép vào thư mục đích.

Dưới đây là một ví dụ về một bản sao thư mục có và không có --no-target-directory:

$ mkdir a
$ touch a/b a/c
$ find
.
./a
./a/c
./a/b
$ cp -r a b       # b does not exist; becomes copy of a
$ find
.
./b
./b/b
./b/c
./a
./a/c
./a/b
$ rm -r b
$ mkdir b
$ cp -r a b       # b already exists; a is copied *underneath* it
$ find
.
./b
./b/a
./b/a/b
./b/a/c
./a
./a/c
./a/b
$ rm -r b
$ mkdir b
$ cp -r --no-target-directory a b     # b already exists; becomes copy of a
$ find
.
./b
./b/b
./b/c
./a
./a/c
./a/b

Bạn có thể đạt được một cái gì đó có cùng hiệu ứng bằng cách thêm (các) tên thư mục nguồn với dấu gạch chéo /.như trong: cp -r a/. bsao chép thư mục nguồn a vào b và không bên dưới b .

Cả hai phương pháp trên đều giống như nói "chỉ sao chép nội dung của thư mục nguồn vào đích hiện tại" vì nếu bạn yêu cầu giữ thời gian và quyền, thư mục đích hiện tại sẽ có được thời gian và quyền của thư mục nguồn. Một ví dụ (được chỉnh sửa để xóa thông tin không cần thiết):

$ find . -ls
drwx------   Oct 13 13:31 ./b         # note date and permissions
drwxr-xr-x   Jan  1  2013 ./a         # note date and permissions
-rw-r--r--   Oct 13 13:23 ./a/c
-rw-r--r--   Oct 13 13:23 ./a/b
$ cp -rp --no-target-directory a b    # preserve mode and timestamps
$ find . -ls
drwxr-xr-x   Jan  1  2013 ./b         # note copied date and permissions
-rw-r--r--   Oct 13 13:23 ./b/b
-rw-r--r--   Oct 13 13:23 ./b/c
drwxr-xr-x   Jan  1  2013 ./a
-rw-r--r--   Oct 13 13:23 ./a/c
-rw-r--r--   Oct 13 13:23 ./a/b

Một bản sao chỉ có nội dung sẽ không chuyển chế độ hoặc dấu thời gian của thư mục nguồn sang thư mục đích.


2

Làm thế nào về sau đây?

$ cp -rvT Dir_1 Dir_2
‘Dir_1/File_3.txt’ -> ‘Dir_2/File_3.txt’
‘Dir_1/File_1.txt’ -> ‘Dir_2/File_1.txt’
‘Dir_1/File_2.txt’ -> ‘Dir_2/File_2.txt’
$ cp -rv Dir_1 Dir_2
‘Dir_1’ -> ‘Dir_2/Dir_1’
‘Dir_1/File_3.txt’ -> ‘Dir_2/Dir_1/File_3.txt’
‘Dir_1/File_1.txt’ -> ‘Dir_2/Dir_1/File_1.txt’
‘Dir_1/File_2.txt’ -> ‘Dir_2/Dir_1/File_2.txt’

Như vậy, đó chỉ là một cách viết khác cp Dir_1/* Dir_2/. Tuy nhiên, nó bắt các tệp ẩn ở thư mục gốc của Dir_1 sẽ bị bỏ qua bởi một cách đơn giản cp *.

$ touch Dir_1/.Hidden_File_{1,2,3}.txt
$ cp -rv Dir_1/* Dir_2
cp: No match.
$ cp -rvT Dir_1 Dir_2
‘Dir_1/.Hidden_File_2.txt’ -> ‘Dir_2/.Hidden_File_2.txt’
‘Dir_1/.Hidden_File_3.txt’ -> ‘Dir_2/.Hidden_File_3.txt’
‘Dir_1/.Hidden_File_1.txt’ -> ‘Dir_2/.Hidden_File_1.txt’

hoạt động với tôi với --no-target-directorytùy chọn [out] : miễn là tôi sử dụng --recursive, mọi thứ đều ổn [với coreutils 8.12GNU / Linux]. Sự khác biệt chính dường như là với --no-target-directorynội dung nhưng bản thân thư mục không được sao chép [nghiên cứu vẫn đang được tiến hành]
erch
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.