sed
tạo một tệp tạm thời, ghi đầu ra vào tệp đó và sau đó đổi tên tệp tạm thời trên đầu của bản gốc.
Bạn có thể xem những gì xảy ra bằng cách sử dụng strace
:
$ strace -e trace=file sed -i -e '' a
execve("/usr/bin/sed", ["sed", "-i", "-e", "", "a"], [/* 34 vars */]) = 0
<...trimmed...>
open("a", O_RDONLY) = 3
open("./sedxvhRY8", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
rename("./sedxvhRY8", "a") = 0
+++ exited with 0 +++
Thao tác này ghi lại tất cả các thao tác tệp sed
tạo ra: nó tạo một tệp mới (an toàn với O_CREAT|O_EXCL
), ghi dữ liệu vào đó và sau đó di chuyển nó trở lại trên đầu tệp gốc của tôi a
.
sed -i
chấp nhận một hậu tố để sử dụng cho một bản sao lưu, và trong trường hợp đó, nó di chuyển bản gốc ra khỏi đầu tiên (thay vì đổi tên trên đầu trang). Đối số đó là bắt buộc trong hầu hết các BSD sed
. Trong trường hợp này, có một thời gian ngắn khi không có tệp nào đúng tên trong thư mục cả.
perl
trong các phiên bản gần đây sẽ mở tệp đầu vào, sau đó xóa tệp đó và tạo một tệp mới có cùng tên:
open("a", O_RDONLY) = 3
unlink("a") = 0
open("a", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
Khi bạn xóa ( unlink
) một tệp bạn đã mở, bạn sẽ giữ quyền truy cập vào nó miễn là bạn giữ tay cầm xung quanh, để nó có thể tiếp tục đọc dữ liệu ra khỏi tệp đã bị xóa. Theo cách này, perl
ghi trực tiếp vào tệp đầu ra, thay vì vào tệp tạm thời: không có tệp bổ sung nào được tạo, nhưng nếu bạn đọc tệp trong quá trình, bạn sẽ nhận được một phần nội dung, không giống như sed
cách tiếp cận. Cũng có một thời gian ngắn khi không có tệp nào có tên đúng, đó là lúc bắt đầu quá trình chứ không phải là kết thúc (như trong sed -i .bak
).
Cả hai sed
và perl
sẽ:
- Thay thế một liên kết tượng trưng bằng một tập tin thông thường.
- Phá vỡ liên kết cứng.
- Bảo toàn quyền sở hữu nhóm nếu có thể.
- Tạo tệp với nhóm mặc định của bạn (hoặc nhóm của thư mục mẹ nếu thư mục đó có
setgid
bit) nếu nó thuộc sở hữu của một nhóm bạn không thuộc và bạn không root.
- Giữ quyền sở hữu tập tin nếu bạn root.
- Bảo toàn quyền cơ bản.
- Bảo toàn
setuid
và setgrp
bit, nếu nhóm kết quả giống với nhóm mà nó bắt đầu.
- Bảo quản bit dính.
- Không bảo quản xattrs.
sed
sẽ:
- Bảo tồn ACL (Trên Linux; tôi không biết về người khác) .
perl
sẽ:
Điều trên đúng với Linux với GNU sed
và Mac OS X với (có nguồn gốc FreeBSD) sed
.