天天看點

docker中執行sed: can't move '/etc/resolv.conf73UqmG' to '/etc/resolv.conf': Device or resource busy錯誤的處理原因及方式

錯誤現象

在docker容器中想要修改

/etc/resolv.conf

中的namesever,使用sed指令進行執行時遇到錯誤:

/ # sed -i 's/192.168.1.1/192.168.1.254/g' /etc/resolv.conf
sed: can't move '/etc/resolv.conf73UqmG' to '/etc/resolv.conf': Device or resource busy
           

但是可以通過vi/vim直接修改這個檔案

/etc/resolv.conf

這個檔案的内容。

問題原因

sed指令的實質并不是修改檔案,而是産生一個新的檔案替換原有的檔案。這裡我們做了一個實驗。

我先建立了一個

test.txt

的檔案,檔案内容是

123

。然後我使用

sed

指令對檔案内容進行了替換。再次檢視

test.txt

/ # stat test.txt 
  File: test.txt
  Size: 4         	Blocks: 8          IO Block: 4096   regular file
Device: fd28h/64808d	Inode: 265         Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2017-07-04 06:28:35.000000000
Modify: 2017-07-04 06:28:17.000000000
Change: 2017-07-04 06:29:03.000000000

/ # cat test.txt 
123
/ # sed -i 's/123/321/g' test.txt
/ # stat test.txt 
  File: test.txt
  Size: 4         	Blocks: 8          IO Block: 4096   regular file
Device: fd28h/64808d	Inode: 266         Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2017-07-04 06:29:31.000000000
Modify: 2017-07-04 06:29:31.000000000
Change: 2017-07-04 06:29:31.000000000

/ # cat test.txt
321
           

可以看到檔案内容被正确修改了,但是同時,檔案的inode也修改了。說明了實質上是新生成的檔案替換了原有的檔案。但是vim/vi是在原檔案基礎上修改的,是以inode沒有變化。

在docker中,

/etc/resolv.conf

是通過挂載入容器的。是以當你想去删除這個挂載檔案,也就是挂載點時,自然就會報

Device or resource busy

這個跟是不是特權privilege沒有關系。即使是privilege的容器,也會有這個問題。
/ # rm /etc/resolv.conf 
rm: can't remove '/etc/resolv.conf': Device or resource busy
           

其實不僅僅

/etc/resolv.conf

,還有

/etc/hostname

/etc/hosts

等檔案都是通過挂載方式挂載到容器中來的。是以想要用sed對他們進行修改,都會遇到這樣的問題。我們可以通過

df -h

檢視容器内的挂載情況。

/ # df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/mapper/docker-253:2-807144231-37acfcd86387ddcbc52ef8dac69d919283fc5d9d8ab5f55fd23d1c782e3b1c70
                         10.0G     33.8M     10.0G   0% /
tmpfs                    15.4G         0     15.4G   0% /dev
tmpfs                    15.4G         0     15.4G   0% /sys/fs/cgroup
/dev/mapper/centos-home
                        212.1G    181.8G     30.3G  86% /run/secrets
/dev/mapper/centos-home
                        212.1G    181.8G     30.3G  86% /dev/termination-log
/dev/mapper/centos-home
                        212.1G    181.8G     30.3G  86% /etc/resolv.conf
/dev/mapper/centos-home
                        212.1G    181.8G     30.3G  86% /etc/hostname
/dev/mapper/centos-home
                        212.1G    181.8G     30.3G  86% /etc/hosts
shm                      64.0M         0     64.0M   0% /dev/shm
tmpfs                    15.4G         0     15.4G   0% /proc/kcore
tmpfs                    15.4G         0     15.4G   0% /proc/timer_stats
           

如何解決

使用vi固然可以,但是對于批量操作就不是很合适了。可以通過sed和echo的組合指令

echo "$(sed 's/192.168.1.1/192.168.1.254/g' /etc/resolv.conf)" > /etc/resolv.conf

即可實作替換。

/ # cat /etc/resolv.conf 
search default.svc.games.local svc.games.local games.local
nameserver 192.168.1.1
options ndots:5
/ # echo "$(sed 's/192.168.1.1/192.168.1.254/g' /etc/resolv.conf)" >  /etc/resolv.conf
/ # cat /etc/resolv.conf 
search default.svc.games.local svc.games.local games.local
nameserver 192.168.1.254
options ndots:5
           
這裡如果使用

sed 's/192.168.1.1/192.168.1.254/g' /etc/resolv.conf > /etc/resolv.conf

是無效的。最終會導緻

/etc/resolv.conf

内容為空。

作者:xuxinkun

出處:xinkun的部落格

連結:https://www.cnblogs.com/xuxinkun/

本文版權歸作者所有,歡迎轉載。

未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

歡迎掃描右側二維碼關注微信公衆号

xinkun的部落格 進行訂閱。也可以通過微信公衆号留言同作者進行交流。
docker中執行sed: can't move '/etc/resolv.conf73UqmG' to '/etc/resolv.conf': Device or resource busy錯誤的處理原因及方式