Đây có phải là một UUOC (sử dụng con mèo vô dụng) để chuyển hướng tập tin này sang tập tin khác không?


36

Nếu tôi muốn làm cho nội dung file2phù hợp với nội dung của file1, rõ ràng tôi có thể chạy cp file1 file2.

Tuy nhiên, nếu tôi muốn giữ mọi thứ về file2 ngoại trừ chủ sở hữu, quyền, thuộc tính mở rộng, ACL, liên kết cứng, v.v., thì tôi sẽ không muốn chạy cp. * Trong trường hợp đó tôi chỉ muốn mở nội dung file1vào file2.

Có vẻ như sau đây sẽ làm điều đó:

< file1 > file2

Nhưng nó không hoạt động. file2bị cắt cụt thành không có gì và không được viết thành. Tuy nhiên,

cat < file1 > file2

không làm việc

Nó làm tôi ngạc nhiên rằng phiên bản đầu tiên không hoạt động.

Phiên bản thứ hai có phải là UUOC không? Có cách nào để làm điều này mà không cần gọi lệnh, chỉ bằng cách sử dụng chuyển hướng?

Lưu ý: Tôi biết rằng UUOC là một điểm mang tính mô phạm hơn là một mô hình chống thực sự.

* Như tniles09 đã phát hiện ra , trên thực tế cp sẽ hoạt động trong trường hợp này.


3
Cho dù < file1 > file2những gì bạn muốn là phụ thuộc vào vỏ.
Michael Homer

13
Chà, nó một cách sử dụng vô dụng của <...
jwodder

2
một mô hình chống là gì?
mikeerv

6
@jwodder - Điều đó không đúng. đặc biệt là khi bạn đang nói về một bản sao. xem xét những gì xảy ra khi file1không tồn tại hoặc không thể đọc được và bạn mở nó < trước khi > đầu ra được mở, và sau đó xem xét những gì xảy ra khi bạn cho phép catthử mở nó.
mikeerv

3
@JonathanLeffler Trong zsh một lệnh trống với các lệnh gọi chuyển hướng cat(theo mặc định), về cơ bản là chạy lệnh thứ hai. Xem câu trả lời của Stéphane Chazelas bên dưới để biết nhiều hơn về điều đó hơn là phù hợp với một nhận xét.
Michael Homer

Câu trả lời:


58

cat < file1 > file2không phải là một UUOC. Cổ điển <>thực hiện chuyển hướng tương ứng với các bản sao mô tả tệp ở cấp hệ thống. Bản thân bộ mô tả tệp không thực hiện một điều gì (tốt, các >chuyển hướng mở với O_TRUNC, để chính xác, các chuyển hướng đầu ra sẽ cắt bớt tệp đầu ra). Đừng để các < >biểu tượng làm bạn bối rối. Chuyển hướng không di chuyển dữ liệu mà họ gán mô tả tệp cho các mô tả tệp khác.

Trong trường hợp này, bạn mở file1và gán bộ mô tả tệp đó cho bộ mô tả tệp 0( <file1== 0<file1) file2và gán bộ mô tả tệp đó cho bộ mô tả tệp 1( >file2== 1>file2).

Bây giờ bạn đã có hai phần mô tả tệp, bạn cần một quy trình để xử lý dữ liệu giữa hai phần mềm và đó là những gì catdành cho.


11
Có lẽ đó chỉ là tôi, nhưng phần yêu thích của tôi trong câu trả lời này là việc bạn sử dụng từ "xẻng". :) Rất rõ ràng, cảm ơn bạn.
tự đại diện

1
@Wildcard Tôi đã thích "bơm" hơn "xẻng", nhưng vẫn là một từ tốt. +1
Mehrdad

Tại sao xẻng là một từ tốt?
bubakazouba

1
Người ta xúc một đống bụi bẩn, một cái xẻng đầy một lúc, từ đống này sang đống khác khi dữ liệu được sao chép bộ đệm bằng bộ đệm. Đó là một sự tương tự tốt.
bsd

1
Trong câu đầu tiên của bạn, bạn nói rằng các mô tả tập tin đang được sao chép. Có phải chúng đang được sao chép hoặc gán lại (như đoạn thứ hai của bạn và hành vi của tính năng, dường như chỉ ra)?
Greg Bell

17

Không phải, vì như những người khác đã chỉ ra, hành vi trong câu hỏi phụ thuộc vào vỏ. Như bạn (OP) đã chỉ ra, đây là một chút mang tính mô phạm , thậm chí có thể hài hước? , loại chủ đề.

Tuy nhiên, trên các hệ thống GNU, tiền đề ban đầu của bạn có sẵn một giải pháp khác : cp --no-preserve=all file1 file2. Hãy thử điều này, tôi nghĩ rằng nó sẽ đáp ứng tình huống được mô tả của bạn (ví dụ: sửa đổi nội dung file2trong khi không sửa đổi các thuộc tính của nó).

Ví dụ :

$ ls -l
    total 8
    -rw-r--r-- 1 tniles sambashare 16 Dec 16 12:21 fezzik
    -rw-r--r-- 1 tniles tniles     14 Dec 16 12:16 fred
$ cat *
    Lookout, world!
    Hello, world!
$ cp --no-preserve=all fred fezzik 
$ ls -l
    total 8
    -rw-r--r-- 1 tniles sambashare 14 Dec 16 12:22 fezzik
    -rw-r--r-- 1 tniles tniles     14 Dec 16 12:16 fred
$ cat *
    Hello, world!
    Hello, world!

CẬP NHẬT Trên thực tế, tôi chỉ nhận thấy rằng chính hệ thống của tôi cpdường như bảo tồn các thuộc tính trừ khi -ahoặc -pđược chỉ định. Tôi đang sử dụng bash shell và GNU coreutils. Tôi đoán bạn học được một vài thứ mới mỗi ngày...


Kết quả kiểm tra (bằng Wildcard) bao gồm liên kết cứng và các quyền khác nhau:

$ ls -li
total 12
913966 -rw-rw-r-- 1 vagrant vagrant 30 Dec 16 20:26 file1
913965 -rwxrw---- 2 pete    vagrant 39 Dec 16 20:35 file2
913965 -rwxrw---- 2 pete    vagrant 39 Dec 16 20:35 hardlinktofile2
$ cat file1
This is the contents of file1
$ cat file2
This is the original contents of file2
$ cp file1 file2
$ ls -li
total 12
913966 -rw-rw-r-- 1 vagrant vagrant 30 Dec 16 20:26 file1
913965 -rwxrw---- 2 pete    vagrant 30 Dec 16 20:37 file2
913965 -rwxrw---- 2 pete    vagrant 30 Dec 16 20:37 hardlinktofile2
$ cat file1
This is the contents of file1
$ cat file2
This is the contents of file1
$ 

Tốt đẹp. Tôi đã chạy thử nghiệm của riêng mình bao gồm một liên kết cứng và các quyền khác nhau và có vẻ như bạn đã đúng.
tự đại diện

Đã thêm kết quả kiểm tra của tôi; hy vọng bạn không phiền :) Tôi đã không kiểm tra ACL hoặc các thuộc tính mở rộng nhưng cho rằng số inode được giữ nguyên Tôi chắc chắn 99% chúng cũng sẽ như vậy.
tự đại diện

Đẹp ... đừng bận tâm chút nào. :-)
tniles

13

Trong zsh, vỏ nơi < file1 > file2làm việc, vỏ không gọi cat.

Đối với một dòng lệnh chỉ bao gồm các chuyển hướng và không có lệnh cũng như các phép gán, các lệnh zshgọi $NULLCMD( cattheo mặc định) trừ khi chuyển hướng duy nhất là một <trong trường hợp $READNULLCMD( pagertheo mặc định) được gọi thay thế. (đó là trừ khi zshtrong shhoặc cshmô phỏng trong trường hợp nó hoạt động giống như vỏ nó mô phỏng).

Vì thế:

< file1 > file2

thực sự giống như

cat < file1 > file2

< file1

giống như

pager < file1

Đối với bản ghi, cú pháp này không hoạt động cho ksh93
fpmurphy

8
< from > to

không hoạt động vì không có lệnh ở đó; không có quá trình Shell mở / tạo các tệp và sắp xếp các chuyển hướng (có nghĩa là các mô tả tệp tham chiếu các tệp này được trồng là 0 và 1: đầu vào tiêu chuẩn và đầu ra tiêu chuẩn). Nhưng không có gì để thực hiện một vòng lặp để đọc từ đầu vào tiêu chuẩn và ghi vào đầu ra tiêu chuẩn.

zshlàm cho công việc này bằng cách thay thế một lệnh có thể cấu hình người dùng trong trường hợp "lệnh null" này. Lệnh không hiển thị trong dòng lệnh, nhưng nó vẫn ở đó. Một quy trình được tạo ra cho nó và nó hoạt động theo cùng một cách. NULLCMDcattheo mặc định, vì vậy < from > tothực sự có nghĩa là cat < from > to trong zsh, trừ khi NULLCMDđược thiết lập để cái gì khác; đó là một lệnh "mèo ngầm".

"Việc sử dụng mèo vô dụng" xảy ra khi catđược sử dụng như một trung gian để đọc từ tệp và đưa dữ liệu sang quy trình khác, mô tả tệp có thể được kết nối với tệp gốc.

Nếu catcó thể tháo rời khỏi tình huống, như vậy các lệnh còn lại vẫn có thể thực hiện cùng một tác vụ, thì nó là vô ích. Nếu nó không thể tháo rời, thì nó không vô dụng.

# useless, removable:
$ cat archive.tar | tar tf -    #  -->  tar tf archive.tar

# not removable (in POSIX shell):
$ cat > file
abc
[Ctrl-D]

# likewise:
STRING=$(cat file)

Một catđó là replacable không phải là điều tương tự. Ví dụ thay vì cat > filechúng ta có thể sử dụng vi fileđể tạo tập tin. Điều đó không được tính là loại bỏ cat, trong khi sử dụng bất cứ thứ gì còn lại để đạt được cùng một nhiệm vụ.

Nếu catlà lệnh duy nhất trong đường ống, thì dĩ nhiên nó không thể bị xóa; không sắp xếp lại bất cứ thứ gì còn lại sẽ làm công việc tương đương.

Một số kịch bản lệnh shell sử dụng catvì họ nghĩ rằng nó cho phép họ di chuyển toán hạng đầu vào gần bên trái của dòng lệnh. Tuy nhiên, chuyển hướng có thể là bất cứ nơi nào trong dòng lệnh:

# If you're so inclined:
# move source archive operand to the left without cat:
$ < archive.tar tar xf - > listing

btw, bạn không phải sử dụng f -cho tar. tar xf -chỉ là tar x.
dnt

@mikeerv Nó nói ở đâu catcó liên quan đến việc tạo tập tin? Trả lời rõ ràng rằng vỏ làm điều này. Vấn đề với > filebạn đang đề cập đến là gì? Tôi thường sử dụng nó một mình để cắt một tập tin hiện có đến độ dài bằng không hoặc đảm bảo tồn tại như vậy. Câu hỏi này là về lý do tại sao < from > tokhông hoạt động như thế cat < from > to, và UUoC, không phải "vui lòng cho tôi biết lý do tại sao catkhông phải là một thay thế tốt cho cp".
Kaz

1
@dnt, tarlà người lưu trữ băng . Nhiều tartriển khai vẫn hoạt động với thiết bị băng đầu tiên theo mặc định.
Stéphane Chazelas

1

< file1 > file2 Có vẻ như phụ thuộc vào vỏ, trên zsh nó hoạt động, trên bash không.

chỉnh sửa: xóa tuyên bố sai


cp -abảo tồn các thuộc tính của tệp1ghi đè lên các thuộc tính của tệp2. Đối diện với hành vi mong muốn. Ngoài ra, tôi không thể biết ngay cả khi nhìn vào trang người đàn ông những gì sẽ xảy ra với các liên kết cứng, nhưng tôi nghĩ rằng sẽ an toàn khi nói rằng các liên kết cứng của tệp2 sẽ không được bảo tồn.
tự đại diện

Bạn nói đúng, tôi đã không đọc câu hỏi đủ cẩn thận.
ngontea

1

Ngoài tất cả các câu trả lời hay, bạn có thể tránh UUOC bằng cách mô phỏng a cat:

awk 1 file1 > file2   # For line-oriented text, not binaries.
dd if=file1 of=file2  # Works for binary files, too.
# many more geeky ways.

Các lệnh này không sao chép dữ liệu meta tệp, như một cách đơn giản cp.


Đúng, nhưng điều đáng nói là chúng không có lợi thế và chỉ có nhược điểm (hiệu suất, độ tin cậy) hơn cat. Ở đây bạn cần một lệnh để chuyển dữ liệu giữa hai mô tả tệp và catlà một trong những lệnh tốt nhất cho điều đó. Xem thêm pvcái nào có thể sử dụng splice()trên Linux cho fifos, (mặc dù nó không fadvise(POSIX_FADV_SEQUENTIAL)giống như GNU cat).
Stéphane Chazelas

Các ddlệnh cho các tập tin nhị phân có vẻ tốt ... hoặc sẽ catlàm việc cũng như cho các tập tin nhị phân?
tự đại diện

@Wildcard catcũng hoạt động cho các tệp nhị phân (Unix thường không phân biệt; tuy nhiên, một số công cụ cụ thể hoạt động theo từng dòng, như awk, grep, wc, ... POSIX cũng xác định độ dài dòng lớn nhất tối thiểu, theo lý thuyết một công cụ định hướng dòng có thể từ chối xử lý các dòng quá lớn.)
Jens

2
@ StéphaneChazelas Câu trả lời này cũng được dự định là nói bằng lưỡi. Có vẻ như, mặc dù mùa, một số người dị ứng với niềm vui (không hướng vào bạn; tôi đánh giá cao chuyên môn vỏ của bạn và các tiêu chuẩn Opengroup hoạt động).
Jens

sed '' < file1 > file2;-)
Chấn thương kỹ thuật số

0

Nếu nó hoạt động, đừng sửa nó.

tôi sẽ dùng

cat < file1 > file2

và không đổ mồ hôi cho PC của ngữ nghĩa.

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.