9

This problem only happen in docker container.

Only find is fine:

find ${BASIN_SPIDER_CONFIG_PATH} -type f -name "*.json"

find with sed

find ${BASIN_SPIDER_CONFIG_PATH} -type f -name "*.json"|xargs sed -i "s/10.142.55.199/host02/g"

gives an error:

/xxx/config/sed8Ey5tD: Device or resource busy

I don't understand what is sed8Ey5tD , ls can't see it. I think it is by docker, but can't figure it out.

How to make sed success?


OK, I found that file is being volumed by docker , there is volumes: /xxx/config.json : /xxx/config/config.json in docker-compose.yml. After docker-compose down, the file can be edit . But how do I edit the file without docker-compose down ?

  • It's temporary file created by sed. When you do in-place modification, sed will create a temporary file to work on to prevent corrupting your original. If anything went right, then it replace the original with temporary one. But what is your question? You want to know which cause that error or what is sed8Ey5tD file? – cuonglm Nov 13 '17 at 8:44
  • @cuonglm I want to know how to make sed success. – Mithril Nov 13 '17 at 9:13
  • are you sure that you have write permissions inside the container? – user1700494 Nov 13 '17 at 9:22
  • @user1700494 root user – Mithril Nov 13 '17 at 9:23
  • you may try to force sed to make no backup file xargs sed -i'' "s/10.142.55.199/host02/g" (add single quotes right after -i key) – user1700494 Nov 13 '17 at 9:26
9

Yes, as you found, the file is mounted by docker, which means you are not allowed to change its inode from within docker container. But, what if you only change the content of file without touching its inode, does it work? Sure, it does. So all you need to do is to find a way to change the content of original file only, rather than create a new file and then replace the original one.

Command sed with option -i does create new file, and then replace the old file with the new one, which definitely will change the file inode. That is why it gives you the error.

So, which ways can change the content of file? Many many ways.

  1. shell redirect, e.g., echo abc > file
  2. command cp, e.g., cp new old
  3. vim
  4. ed

Give you several examples for how to fix your issue:

The cp way:

find ${BASIN_SPIDER_CONFIG_PATH} -type f -name "*.json" | xargs -L1 bash -c 'sed "s/10.142.55.199/host02/g" $1 > /tmp/.intermediate-file-2431; cp /tmp/.intermediate-file-2431 $1;' --

The vim way

cat > /tmp/vim-temp-script <<EOF
:set nobackup backupcopy=yes
:let i = 0
:while 1
:  let i += 1
:  %s/10.142.55.199/host02/g
:  if i >= argc()
:    break
:  endif
:  wn
:endwhile
:wq
EOF
find ${BASIN_SPIDER_CONFIG_PATH} -type f -name "*.json" | xargs vim -s /tmp/vim-temp-script

The ed way

find ${BASIN_SPIDER_CONFIG_PATH} -type f -name "*.json"|xargs -L1 bash -c 'ed $1 <<EOF
,s/10.142.55.199/host02/g
wq
EOF' --
0

Imho, the easiest way to do is by using the following in a Dockerfile:

RUN cp /etc/hosts /etc/hosts2 && sed -i 's/::1  localhost/::1/g' /etc/hosts2
CMD cat /etc/hosts2 >> /etc/hosts

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.