Làm thế nào để chuyển hướng trong một biểu tượng làm việc theo trình tự?


7

Tôi có file1, file2, file3.


tập tin 1 chứa 1

tập tin 2 chứa 2

tập tin 3 chứa 3

Tôi sử dụng lệnh

cat file1 > file2 > file3

Kết quả trong:

tập tin1 1

file2 (không chứa gì)

tập tin3 1


Tại sao bất cứ điều gì dọc theo dòng này bị phá hủy? Về cơ bản những gì tôi không nhìn thấy đằng sau hậu trường?

(Ghi chú bên sử dụng "chắp thêm" >>thậm chí còn lạ hơn)


Kiểm tra câu trả lời của Muru bên dưới nếu bạn muốn có câu trả lời về cách lệnh thực sự hoạt động ở cấp độ thấp hơn!
Không có thời gian

Câu trả lời:


14

Chuyển hướng trong các vỏ kiểu Bourne / POSIX như bash , dash, ksh, v.v.

xử lý theo thứ tự chúng xuất hiện, từ trái sang phải

> x mở và cắt tệp x, và đặt bộ mô tả tệp ghi vào xđầu ra tiêu chuẩn. Lệnh của bạn:

cat file1 > file2 > file3

Sẽ:

  1. Mở và cắt ngắn file2
  2. Đặt đầu ra tiêu chuẩn để ghi vào bộ mô tả tệp đó
  3. Mở và cắt ngắn file3
  4. Đặt đầu ra tiêu chuẩn để ghi vào bộ mô tả tệp đó
  5. Chạy cat file1

Kết quả cuối cùng là điểm đầu ra tiêu chuẩn vào file3thời điểm catchạy. Cả hai file2file3có nội dung hiện tại của chúng bị xóa, và file3nhận đầu ra của cat(nội dung của file1) được ghi vào đó.


Nếu bạn muốn chia đầu ra thành nhiều luồng được ghi thành các tệp riêng biệt, bạn có thể sử dụngtee :

cat file1 | tee file2 > file3

Các shell khác ( đáng chú ýzsh ) hoạt động khác nhau và lệnh của bạn sẽ có kết quả mà bạn có thể mong đợi: cả hai file2file3sẽ có nội dung file1.


Lưu ý rằng catkhông cần thiết ở đây; <chuyển hướng đầu vào cũng sẽ làm công việc này.


Tôi ước tôi có thể chấp nhận cả câu trả lời của bạn và @muru vì đối với zsh, nó thực hiện theo cách tôi mong đợi ban đầu.
Không có thời gian

Mặc dù catcó thể không cần thiết, một số lệnh đọc từ tệp đầu vào là. < inputfile > outputfilesẽ chỉ cắt bớt tệp đầu ra, nó sẽ không sao chép tệp đầu vào vào nó.
Barmar 4/2/2015

Đó là một phường UUOC ưu tiên cho teelệnh. < x > ythực sự làm việc trong zsh, mặc dù.
Michael Homer

Tôi nhớ alta vista. . (liên kết chứa tham chiếu đến alta vista) Có vẻ như một công thức sẽ hoạt động ở đây để giải thích sự tương tác, giống như mọi thứ > or <phải đối diện nhau để giữ cho dữ liệu được truyền đi. Nhưng tôi thực sự không biết chắc chắn và quá mệt mỏi để suy nghĩ.
Không có thời gian

9

Khi bạn chuyển hướng một fd nhiều lần, tất cả các chuyển hướng sẽ được thực hiện và lần cuối cùng:

$ strace -f -e open bash -c 'cat file1 > file2 > file3'
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
...
[pid 20508] open("file2", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
[pid 20508] open("file3", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
...
[pid 20508] open("file1", O_RDONLY)     = 3

Vì vậy, file2đã được mở và cắt ngắn, và sau đó file3đã được mở.


Vì vậy, điều này thực sự chạy lệnh thông qua như nó sẽ thông qua c?
Không có thời gian

@NoTime nếu bạn đang nói về strace, nó chạy lệnh theo cách nó thường chạy, nhưng liệt kê các cuộc gọi hệ thống được thực hiện. Chúng có thể được tạo bằng bất kỳ ngôn ngữ nào mà api hệ thống có sẵn. Strace giống như một trình gỡ lỗi trong khía cạnh đó.
muru

Điều đó thật tuyệt vời, có lẽ đã trả lời câu hỏi của tôi ít nhiều ngay tại đó. Vì vậy, về cơ bản, nó giống như đặt một biến số 200 lần, thực sự không có vấn đề gì với 199 đầu tiên. (Chỉ tôi cố gắng làm tương tự cho chính mình)
Không có thời gian

@ Không có thời gian, đó là cách tôi nhìn thấy nó. Và đó là lý do tại sao hành vi của zsh, trong khi chắc chắn hữu ích hơn, đánh vào tôi là phản trực giác.
muru 4/2/2015

Tôi nghĩ rằng câu trả lời của bạn là tuyệt vời. Tôi không chắc nó sẽ hữu ích với nhiều người như vậy (nó cực kỳ hiệu quả đối với tôi) vì vậy tôi đã không chấp nhận nó (xin lỗi). Nhưng tôi nêu lên một trong những câu hỏi tuyệt vời khác của bạn.
Không có thời gian
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.