Sed 原地替換文件時(shí)遇到的趣事
哈嘍大家好,我是咸魚
在文章《三劍客之 sed》中咸魚向大家介紹了文本三劍客中的 sed
sed 全名叫 stream editor,流編輯器,用程序的方式來(lái)編輯文本
那么今天咸魚打算講一下我在用 sed 原地替換文件時(shí)遇到的趣事
sed 讓文件屬性變了?
有這么一個(gè)普通文件 test.txt ,內(nèi)容如下:
圖片
link_test.txt 是一個(gè)軟鏈接(Symbolic Link,也可以叫符號(hào)鏈接)文件,指向 test.txt 文件
圖片
軟鏈接文件類似于 Windows 的快捷方式,它實(shí)際上是一個(gè)特殊的文件。關(guān)于軟鏈接相關(guān)的內(nèi)容這里不過多介紹
如果我們對(duì)軟鏈接文件內(nèi)容進(jìn)行修改,源文件是會(huì)跟著改變的
圖片
當(dāng)我使用 sed 對(duì)軟鏈接文件 link_test.txt 進(jìn)行內(nèi)容修改時(shí),命令如下
圖片
有趣的現(xiàn)象發(fā)生了:使用 sed 對(duì)軟鏈接文件 link_test.txt 進(jìn)行內(nèi)容修改之后,源文件 test.txt 內(nèi)容沒有變化,軟鏈接文件link_test.txt 的內(nèi)容發(fā)生變化且變成了普通文件
圖片
怎么樣,是不是很神奇?sed 不但把文件內(nèi)容改了,還把文件屬性也給改了
我們用 strace 工具來(lái)查看一下在執(zhí)行 sed 命令時(shí)操作系統(tǒng)做了哪些操作
strace 一個(gè)系統(tǒng)調(diào)用跟蹤工具,它會(huì)跟蹤并記錄命令運(yùn)行期間的系統(tǒng)調(diào)用和信號(hào)
圖片
具體內(nèi)容有點(diǎn)多,我們著重看下關(guān)鍵內(nèi)容
圖片
由上圖可以知道,如果我們使用 sed 對(duì)一個(gè)文件進(jìn)行原地替換,需要有一個(gè)臨時(shí)文件,sed 先把修改內(nèi)容寫入到這個(gè)文件,最后將文件 rename 到原來(lái)的地方
那我的需求是對(duì)軟鏈接文件 link_test.txt 進(jìn)行內(nèi)容修改,軟鏈接文件屬性不變,且源文件的內(nèi)容也跟著改變,有沒有什么方法呢?
也就是說我們希望命令在執(zhí)行的時(shí)候能夠解析出來(lái)軟鏈接文件后面指向的源文件,直接對(duì)源文件進(jìn)行讀--處理--寫,最后 rename
sed 命令有一個(gè)選項(xiàng) --follow-symlinks
圖片
我們?cè)趫?zhí)行的時(shí)候加上這個(gè)選項(xiàng):
圖片
圖片
總結(jié)一下:
- sed 替換的底層邏輯是把更新后的內(nèi)容寫入一個(gè)臨時(shí)文件里面,然后再 rename 這個(gè)臨時(shí)文件
- 這樣就會(huì)使得如果沒有添加 –follow-symlinks 選項(xiàng)的話,對(duì)軟鏈接文件進(jìn)行 sed 操作就會(huì)使得軟鏈文件變成了一個(gè)常規(guī)文件(其實(shí)是那個(gè)臨時(shí)文件重命名導(dǎo)致的)
- 如果要對(duì)軟鏈接文件指向的源文件進(jìn)行操作,就需要添加 –follow-symlinks 選項(xiàng)