21

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 ?

7
  • 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
    Commented Nov 13, 2017 at 8:44
  • @cuonglm I want to know how to make sed success.
    – Mithril
    Commented Nov 13, 2017 at 9:13
  • are you sure that you have write permissions inside the container? Commented Nov 13, 2017 at 9:22
  • @user1700494 root user
    – Mithril
    Commented Nov 13, 2017 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) Commented Nov 13, 2017 at 9:26

3 Answers 3

22

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' --
1
  • could you please share additional documentation that backs your statements about inode in a container. I want to study further. Commented Jan 4 at 1:40
7

sed has a -c option to use with -i so that it does copy instead of move, which makes this work.

This works:

RUN sed -ci "s/localhost/foobar/g" /etc/hosts

Note carefully, however, that sed -ic won't work, as it would make a backup file ending in .c, rather than doing what sed -i -c or sed -ci does.

Cleaned up a docker script today from this learning :)

3
  • 15
    What version of sed are you using? My version, GNU sed 4.7, has no 'c' option. Commented Feb 12, 2021 at 13:05
  • sed 4.8 included in Ubuntu 22.04, does not have the -c option.
    – rustyx
    Commented Dec 16, 2022 at 16:38
  • Adding -c to sed is left as an exercise for the reader :)
    – x-yuri
    Commented Jun 13, 2023 at 4:26
2

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
1
  • avoid duplicating CMD cat /etc/hosts2 > /etc/hosts
    – emvidi
    Commented Oct 19, 2022 at 9:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .