Câu trả lời:
cat /dev/null > file.txt
là một công dụng vô dụng của con mèo .
Về cơ bản cat /dev/null
chỉ đơn giản là kết quả đầu cat
ra 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.txt
sẽ 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 đó cat
là 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.txt
cú 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 true
việc nó được coi là tích hợp "đặc biệt" .
>| file
là một cắt ngắn rõ ràng hơn.
true
bắ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 : > file
sẽ thoát khỏi shell chẳng hạn nếu file
không thể mở để viết bằng shell POSIX) và true
không. POSIX thậm chí còn đề cập đến việc :
có thể hiệu quả hơn true
trê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ú:
sh
hoặc ksh
mô 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, cat
nế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ỏ ( bash
chỉ 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
, cp
và printf
nói chung là (POSIX đòi hỏi chúng)).file
Tuy 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ố cp
triể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/null
kế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 file
như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 file
một null
thiết bị.eval > file
hoặ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
.
cp
và cat
thường không được tích hợp sẵn.
Bây giờ cp /dev/null file
khô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 : > file
trong 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=0
bị bỏ qua. dd if=/dev/null of=file
sẽ 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 file
là 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.
truncate
sẽ có sẵn, nhưng thư viện C >
cũng không unistd
có sẵn?
truncate
là một tiện ích FreeBSD, tương đối gần đây (2008) được thêm vào lõi GNU (mặc dù --size
kiể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 file
sẽ 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.txt
và 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.txt
và muốn xoay nó.
Vì vậy, bạn sao chép, ví dụ, file.txt
và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_process
có 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_process
nó 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 process
mở tệp:
Nếu other_process
mở 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.txt
trong "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_process
vẫ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_process
chú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 > file
và a > file
là a cat /dev/null
và đ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?
echo
triển khai không hỗ trợ -n
(và sẽ xuất ra -n<SPC><NL>
ở đây. printf '' > file.txt
Sẽ dễ mang theo hơn (ít nhất là trên các hệ thống hiện đại / POSIX).