Làm cách nào để ngăn sed -i phá hủy liên kết tượng trưng?


21

Tại sao sed -ithực thi trên symlink sẽ phá hủy liên kết đó và thay thế nó bằng tệp đích? Làm thế nào để tránh điều này?

ví dụ.

$ ls -l pet*
-rw-rw-r-- 1 madneon madneon 4 mar 23 16:46 pet
lrwxrwxrwx 1 madneon madneon 6 mar 23 16:48 pet_link -> pet

$ sed -i 's/cat/dog/' pet_link

$ ls -l pet*
-rw-rw-r-- 1 madneon madneon 4 mar 23 16:48 pet
-rw-rw-r-- 1 madneon madneon 4 mar 23 16:49 pet_link

Và tại sao nó không được coi là một lỗi?

Câu trả lời:


25

Các -i/ --in-placecờ chỉnh sửa một tập tin tại chỗ. Theo mặc định, sedđọc tệp đã cho, xử lý tệp xuất thành tệp tạm thời, sau đó sao chép tệp tạm thời qua bản gốc mà không kiểm tra xem bản gốc có phải là liên kết tượng trưng không.

GNU sedcó một --follow-symlinkscờ, làm cho nó hoạt động như bạn muốn:

$ echo "cat" > pet
$ ln --symbolic pet pet_link
$ sed --in-place --follow-symlinks 's/cat/dog/' pet_link
$ cat pet
dog

6
Nó không chỉnh sửa một tệp tại chỗ, nhưng chỉnh sửa một bản sao tạm thời của tệp trong thư mục hiện tại sau đó di chuyển bản sao tạm thời đó so với bản gốc.
mikeerv 28/03/2015

@mikeerv Tôi đã bỏ qua các chi tiết thực hiện vì câu hỏi là về giao diện. Thật tốt khi biết, cảm ơn!
Anko

1

Đây không phải là một lỗi, đây là do thiết kế vì sednó là trình duyệt S tream ED , không phải là trình chỉnh sửa tệp. Về cơ bản, nó tạo một bản sao và thay thế tệp gốc bằng bản sao. BashFAQ

Ngoài ra, bạn có thể sử dụng exlệnh thay thế có cú pháp tương tự để thay thế, ví dụ:

ex +%s/cat/dog/ge -scwq pet_link

hoặc nhiều tệp:

ex "+bufdo! %s/cat/dog/ge" -scxa **/pet_link*

Nó sẽ không phá hủy các liên kết tượng trưng.

Liên quan: Làm thế nào để tôi ngăn chặn sed phá hủy hardinks?


0

Tôi thấy rằng điều này cũng hoạt động tốt (bảo tồn cả liên kết tượng trưng và liên kết cứng):

sed 's/cat/dog/' pet_link > pet_link.tmp
cat pet_link.tmp > pet_link
rm pet_link.tmp

0

Có một giải pháp mà đôi khi chúng ta sử dụng để ghi vào cùng một tệp như được đọc từ đó. Đây là một đoạn trích từ trang người đàn ông:

   sponge reads standard input and writes it out to the specified file.
   Unlike a shell redirect, sponge soaks up all its input before opening
   the output file. This allows constructing pipelines that read from and
   write to the same file.

   It also creates the output file atomically by renaming a temp file into
   place, and preserves the permissions of the output file if it already
   exists. If the output file is a special file or symlink, the data will
   be written to it.

Đây là một đoạn cho thấy rằng nó có thể bảo tồn các liên kết tượng trưng, ​​mặc dù tôi thường sử dụng nó để bảo vệ các nút:

# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }

rm -f pet pet_link
echo "cat" > pet
pl " Input data file $FILE:"
head -v pet

pl " Results, before sed:"
ln --symbolic pet pet_link
ls -ligG pet pet_link
# sed --in-place --follow-symlinks 's/cat/dog/' pet_link
pe
pe " Results, after sed:"
sed 's/cat/dog/' pet_link | sponge pet_link
head -v pet
ls -ligG pet pet_link

sản xuất:

-----
 Input data file data1:
==> pet <==
cat

-----
 Results, before sed:
1571283 -rw-r--r-- 1 4 Nov 26 23:03 pet
1571286 lrwxrwxrwx 1 3 Nov 26 23:03 pet_link -> pet

 Results, after sed:
==> pet <==
cat
1571283 -rw-r--r-- 1 4 Nov 26 23:03 pet
1571286 lrwxrwxrwx 1 3 Nov 26 23:03 pet_link -> pet

Trên một hệ thống như:

OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.9 (jessie) 
bash GNU bash 4.3.30

Mã bọt biển có sẵn trong một gói nhiều hơn - một số chi tiết:

sponge  soak up standard input and write to a file (man)
Path    : /usr/bin/sponge
Package : moreutils
Home    : http://kitenet.net/~joey/code/moreutils/
Version : 0.52
Type    : ELF 64-bit LSB executable, x86-64, version 1 (SYS ...)

Tại cửa hàng của chúng tôi, chúng tôi đã viết một phiên bản ghi vào một tệp tạm thời cho trường hợp các tệp rất lớn.

Gói này có sẵn trên Debian, Fedora, macOS (thông qua brew), v.v ... chúc mừng,

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.