find and sed string in docker got error ` Device or resource busy`
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.
- shell redirect, e.g.,
echo abc > file
- command
cp
, e.g.,cp new old
- vim
- 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' --
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 :)