Câu trả lời:
cat /dev/null > file.txtlà một công dụng vô dụng của con mèo .
Về cơ bản cat /dev/nullchỉ đơn giản là kết quả đầu catra không có gì. Vâng, nó hoạt động, nhưng nó được nhiều người cau mày vì nó dẫn đến việc gọi một quy trình bên ngoài không cần thiết.
Đó là một trong những điều phổ biến đơn giản vì nó phổ biến.
Sử dụng chỉ > file.txtsẽ hoạt động trên hầu hết các vỏ, nhưng nó không hoàn toàn di động. Nếu bạn muốn hoàn toàn di động, sau đây là những lựa chọn thay thế tốt:
true > file.txt
: > file.txt
Cả hai :và trueđầu ra đều không có dữ liệu và là các phần tử dựng sẵn (trong khi đó catlà một tiện ích bên ngoài), do đó chúng nhẹ hơn và 'phù hợp' hơn.
Cập nhật:
Như tylerl đã đề cập trong bình luận của mình, đó cũng là >| file.txtcú pháp.
Hầu hết các shell đều có một cài đặt sẽ ngăn chúng cắt xén một tệp hiện có thông qua >. Bạn phải sử dụng >|thay thế. Điều này là để ngăn chặn lỗi của con người khi bạn thực sự có ý định nối thêm >>. Bạn có thể bật hành vi với set -C.
Vì vậy, với điều này, tôi nghĩ rằng phương pháp đơn giản nhất, phù hợp nhất và di động để cắt xén một tệp sẽ là:
:>| file.txt
:cũng được POSIX ủy quyền tích hợp và trên thực tế khác với trueviệc nó được coi là tích hợp "đặc biệt" .
>| filelà một cắt ngắn rõ ràng hơn.
truebắt buộc phải được xây dựng và theo truyền thống thì không. :được xây dựng trong tất cả các vỏ của gia đình Bourne. :là một nội dung đặc biệt trên mỗi POSIX (vì vậy : > filesẽ thoát khỏi shell chẳng hạn nếu filekhông thể mở để viết bằng shell POSIX) và truekhông. POSIX thậm chí còn đề cập đến việc :có thể hiệu quả hơn truetrên một số hệ thống.
Bourne POSIX zsh csh/tcsh rc/es fish
> file Y Y N(1) N(1) N N
: > file N/Y(2) Y(3) Y Y(4) N(5) N(5)
true > file Y(5) Y Y Y(5) Y(5) Y(5)
cat /dev/null > file Y(5) Y Y(5) Y(5) Y(5) Y(5)
eval > file Y(3,8) Y(3) Y Y(6) Y Y
cp /dev/null file (7) Y(5) Y Y(5) Y(5) Y(5) Y(5)
printf '' > file Y(5) Y Y Y(5) Y(5) Y
Ghi chú:
shhoặc kshmô phỏng, đối với các chuyển hướng không có lệnh, trong zsh, một lệnh mặc định được giả sử (một máy nhắn tin chỉ chuyển hướng stdin, catnếu không), có thể được điều chỉnh bằng các biến NULLCMD và READNULLCMD. Đó là cảm hứng từ tính năng tương tự trong(t)csh:trong UnixV7 như :đã được giải thích nửa chừng giữa một nhà lãnh đạo bình luận và một lệnh null. Sau đó, chúng giống như tất cả các nội trang, nếu chuyển hướng thất bại, nó thoát khỏi vỏ.:và evalđược tích hợp đặc biệt, nếu chuyển hướng không thành công, nó sẽ thoát khỏi vỏ ( bashchỉ thực hiện điều đó ở chế độ POSIX).(t)cshđó, đó là xác định một nhãn null (cho goto), vì vậy goto ''sẽ có chi nhánh ở đó. Nếu chuyển hướng thất bại, nó thoát khỏi vỏ.$PATH( :thường không phải là; true, cat, cpvà printfnói chung là (POSIX đòi hỏi chúng)).fileTuy nhiên, nếu là một liên kết tượng trưng đến một tệp không tồn tại, một số cptriển khai như GNU sẽ từ chối tạo nó.(phần này rất chủ quan)
> file. Điều đó >trông quá giống như một lời nhắc hoặc một nhận xét. Ngoài ra câu hỏi tôi sẽ hỏi khi đọc rằng (và hầu hết các shell sẽ phàn nàn về điều tương tự) là đầu ra chính xác mà bạn đang chuyển hướng? .: > file. :được gọi là lệnh no-op. Vì vậy, nó đọc ngay lập tức như tạo ra một tập tin trống. Tuy nhiên, ở đây một lần nữa, điều đó :có thể dễ dàng bị bỏ qua và / hoặc được xem như một lời nhắc.true > file: boolean có liên quan gì đến nội dung chuyển hướng hoặc tệp? Có nghĩa là gì ở đây? là điều đầu tiên tôi nghĩ đến khi tôi đọc nó.cat /dev/null > file. Liên /dev/nullkết thành file? catđược thường được xem như lệnh để đổ nội dung của các tập tin, mà vẫn có thể có ý nghĩa: đổ nội dung của các tập tin rỗng vàofile , một chút giống như một cách phức tạp để nói cp /dev/null filenhưng vẫn hiểu.cp /dev/null file. Sao chép nội dung của tập tin trống vào file. Có ý nghĩa, mặc dù ai đó không biết làm thế nào cpđể làm theo mặc định có thể nghĩ rằng bạn cũng đang cố gắng tạo ra filemột nullthiết bị.eval > filehoặc eval '' > file. Chạy không có gì và chuyển hướng đầu ra của nó đến a file. Có nghĩa với tôi. Kỳ lạ là nó không phải là một thành ngữ phổ biến.printf '' > file: in rõ ràng không có gì vào một tập tin. Một trong đó có ý nghĩa nhất đối với tôi.Sự khác biệt sẽ là liệu chúng ta có sử dụng shell dựng hay không. Nếu không, một tiến trình phải được rẽ nhánh, lệnh được tải và thực thi.
evalđược đảm bảo được xây dựng trong tất cả các vỏ. :được tích hợp sẵn ở bất cứ nơi nào có sẵn (Bourne / csh thích). trueđược tích hợp sẵn trong vỏ giống như Bourne.
printfđược tích hợp trong hầu hết các vỏ giống như Bourne hiện đại và fish.
cpvà catthường không được tích hợp sẵn.
Bây giờ cp /dev/null filekhông gọi chuyển hướng vỏ, vì vậy những thứ như:
find . -exec cp /dev/null {} \;
sẽ hiệu quả hơn:
find . -exec sh -c '> "$1"' sh {} \;
(mặc dù không nhất thiết phải hơn:
find . -exec sh -c 'for f do : > "$f"; done' sh {} +
).
Cá nhân, tôi sử dụng : > filetrong các vỏ giống như Bourne, và không sử dụng bất cứ thứ gì khác ngoài các vỏ giống như Bourne ngày nay.
dd of=file count=0?
dd(như ít nhất là của Solaris 10), count=0bị bỏ qua. dd if=/dev/null of=filesẽ di động hơn. Trong mọi trường hợp, đó là độc lập với vỏ.
cp /dev/null file, phải không?
cp /dev/null filelà một thành ngữ phổ biến. Tôi giới hạn ở những điều đó, vấn đề không phải là liệt kê tất cả các cách có thể.
Bạn có thể muốn xem xét truncate, chính xác là: cắt bớt một tập tin.
Ví dụ:
truncate --size 0 file.txt
Điều này có lẽ chậm hơn so với sử dụng true > file.txt.
Tuy nhiên, điểm chính của tôi là: truncateđược dùng để cắt các tệp, trong khi sử dụng> có tác dụng phụ là cắt bớt tệp.
truncatesẽ có sẵn, nhưng thư viện C >cũng không unistdcó sẵn?
truncatelà một tiện ích FreeBSD, tương đối gần đây (2008) được thêm vào lõi GNU (mặc dù --sizekiểu tùy chọn dài GNU là đặc trưng của GNU), do đó, nó không có sẵn trong các hệ thống không phải GNU hoặc FreeBSD và nó không có sẵn trong các hệ thống GNU cũ hơn, Tôi sẽ không nói nó di động. cp /dev/null filesẽ làm việc mà không cần chuyển hướng vỏ và sẽ dễ mang theo hơn.
Câu trả lời phụ thuộc một chút vào cái gì file.txtvà quá trình viết nó như thế nào!
Tôi sẽ trích dẫn một trường hợp sử dụng phổ biến: bạn có một logfile đang phát triển file.txtvà muốn xoay nó.
Vì vậy, bạn sao chép, ví dụ, file.txtvào file.txt.save, sau đó cắt ngắn file.txt.
Trong trường hợp này, NẾU tệp không được mở bằng another_process(ví dụ: another_processcó thể là chương trình xuất ra tệp đó, ví dụ: chương trình ghi nhật ký gì đó), thì 2 đề xuất của bạn là tương đương và cả hai đều hoạt động tốt (nhưng thứ 2 được ưu tiên là "cat / dev / null> file.txt" đầu tiên là cách sử dụng Cat vô dụng và cũng mở và đọc / dev / null).
Nhưng rắc rối thực sự sẽ xảy ra nếu other_processnó vẫn hoạt động và vẫn có một tay cầm mở đi đến file.txt.
Sau đó, 2 trường hợp chính phát sinh, tùy thuộc vào cách other processmở tệp:
Nếu other_processmở nó theo cách thông thường, thì tay cầm sẽ vẫn trỏ đến vị trí cũ trong tệp, ví dụ như ở offset 1200 byte. Do đó, lần ghi tiếp theo sẽ bắt đầu ở offset 1200 và do đó, bạn sẽ lại có một tệp 1200byte (+ bất cứ thứ gì khác được viết), với 1200 ký tự null hàng đầu! Không phải những gì bạn muốn , tôi đoán.
Nếu other_processđược mở file.txttrong "chế độ chắp thêm", thì mỗi lần nó ghi, con trỏ sẽ chủ động tìm đến cuối tệp. Do đó, khi bạn cắt bớt nó, nó sẽ "tìm kiếm" cho đến khi byte 0 và bạn sẽ không có tác dụng phụ xấu! Đây là những gì bạn muốn (... thông thường!)
Lưu ý rằng điều này có nghĩa là bạn cần, khi bạn cắt một tệp, để đảm bảo rằng tất cả other_processvẫn đang ghi vào vị trí đó đã mở nó trong chế độ "chắp thêm". Nếu không, bạn sẽ cần phải dừng other_processchúng lại và khởi động lại chúng để chúng bắt đầu chỉ vào phần đầu của tệp thay vì vị trí cũ.
Tài liệu tham khảo: /programming//a/16720582/1841533 để được giải thích rõ ràng hơn và một ví dụ ngắn về sự khác biệt giữa ghi nhật ký chế độ bình thường và chắp thêm tại /programming//a/984761/1841533
cat /dev/null > filevà a > filelà a cat /dev/nullvà điều đó không tạo ra sự khác biệt cho tệp.
Tôi thích điều này và sử dụng nó thường xuyên vì nó trông sạch sẽ hơn và không giống như ai đó vô tình nhấn phím quay lại:
echo -n "" > file.txt
Có nên tích hợp quá không?
echotriển khai không hỗ trợ -n(và sẽ xuất ra -n<SPC><NL>ở đây. printf '' > file.txtSẽ dễ mang theo hơn (ít nhất là trên các hệ thống hiện đại / POSIX).