如何防止sed -i命令在Linux或Unix上覆盖我的符号链接
时间:2020-01-09 10:40:35 来源:igfitidea点击:
在Debian Linux服务器上运行了sed -i's/CONFIG_1/CONFIG_OPT_2/g'/etc/nginx/sites-enabled/*。 conf
命令。
但是,sed命令破坏了链接并创建了一个常规文件来代替链接文件。
如何防止sed -i命令破坏Linux或类Unix系统上的符号链接?
sed命令编辑文件的-i或--in-place选项。
因此自然会破坏您的链接。
如何在符号链接上安全地使用sed -i命令,以防止sed破坏符号链接?
您必须将--follow-symlinks选项传递给GNU/sed命令,以便在就地处理时遵循符号链接。
语法为:
sed -i --follow-symlinks '...' input sed -i --follow-symlinks 'regex' input
例子
让我们考虑一下/etc/nginx/sites-enabled中的以下文件:
$ cd /etc/nginx/sites-enabled/ $ ls -l
每个文件都是/etc/nginx/sites-available /目录中对应文件的符号链接。
如果运行以下命令,它将破坏所有内容:
$ cd /etc/nginx/sites-enabled/ $ sudo sed -i 's/192.168.1/192.168.1/g' *.conf $ ls -l
输出示例:
drwxr-xr-x 2 root root 4096 Jun 13 16:24 ./ drwxr-xr-x 3 root root 4096 Jun 13 16:23 ../ lrwxrwxrwx 1 root root 34 Jun 13 16:23 default -> /etc/nginx/sites-available/default -rw-r--r-- 1 root root 412 Jun 13 16:24 http.www.theitroad.org.conf -rw-r--r-- 1 root root 2618 Jun 13 16:24 https.www.theitroad.org.conf -rw-r--r-- 1 root root 292 Jun 13 16:24 http.www.theitroad.local.conf -rw-r--r-- 1 root root 2648 Jun 13 16:24 https.dl.theitroad.local.conf -rw-r--r-- 1 root root 3858 Jun 13 16:24 https.www.theitroad.local.conf -rw-r--r-- 1 root root 158 Jun 13 16:24 longview.localhost.conf
为避免此类灾难,请在GNU/Linux sed版本上运行以下命令:
$ cd /etc/nginx/sites-enabled/ $ sudo sed -i --follow-symlinks 's/192.168.1/192.168.1/g' *.conf $ ls -l
sed不再破坏我在GNU/Linux上的符号链接
处理BSD sed(macOS sed)
有多种方法可以处理非GNU/sed版本上的硬链接和软链接。
让我们看一些例子。
打开文件以使用sed进行读写
此语法应在具有GNU和非gnu版本的sed的ksh/sh/bash shell上运行:
## replace foo with bar using any version of sed ## Each file opened using the redirection operator: ## [n]<>word syntax sed 's/foo/bar/g' < input 1<> input ## ## 或者 ## for i in /path/to/dir/*.conf do sed 's/foo/bar/g' < $i 1<> $i done
使用第三个文件
尝试以下语法:
$ cp myfile myfile.bak $ sed 's/foo/bar/g' < myfile.bak > myfile $ rm -f file.bak
使用ed命令
语法为:
$ ed -s link_file
这是使用bash for loop完成的多个文件的示例:
for i in /path/to/dir/*.conf do ed -s $i <<< $',s/foo/bar/g\nw' done
使用ex命令
语法为:
$ ex +%s/foo/bar/e -scwq file_link
或者
for i in /path/to/dir/*.conf do ex +%s/foo/bar/e -scwq $i done
使用Perl
语法很简单
perl -p -i -e 's/foo/bar/g' $(readlink -f file_link) ## 或者 perl -p -i -e 's/foo/bar/g' $(realpath file_link)
您可以使用realpath/readlink命令告诉Perl使用物理路径。