传递变量时sed命令中未终止的Delimeter

时间:2018-02-19 05:52:58

标签: perl nginx sed

我现在已经挣扎了一个多小时了,我不确定是什么错。使用Perl,我尝试使用sed在/etc/nginx/nginx.conf中对字符串进行内联替换,如下面的sed命令所示:

my $replacement_string = getstringforreplace();
my $command = qq ( sudo sed -i "s~default_type        application/octet-stream;~default_type        application/octet-stream;$replacement_string~" /etc/nginx/nginx.conf );
system ( $command );
die ( $command ); # Using this for debugging purposes.

我真的想在匹配'默认类型'之后放置$ replacement_string。在nginx.conf中排队但是我不确定除了sed之外还要使用什么。

我已经(1)改变了分隔符以避免任何正斜杠的问题,(2)双引用替换(我真的不确定为什么,我以前使用单引号),以及(3)删除了$ replacement_string之前的换行符,等等。

我按照this回答中的说明将 die($ command); 放在那里,但我没有看到错误。这就是回归 - 这正是我想要的:

sudo sed -i "s~default_type        application/octet-stream;~default_type        application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;

server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    tserver_name  _;
    root         /usr/share/nginx/html;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}
~" /etc/nginx/nginx.conf

$ replacement_string是通过调用下面的子例程getstringforreplace()返回的:

sub getstringforreplace
{
    my $message = qq (
    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        tserver_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
    );
    return $message;
}

任何指导都会非常感激,因为我不知道如何摆脱这种未终止的'命令问题。我现在想的是它与我调用的子程序中的那个qq()有关。

2 个答案:

答案 0 :(得分:1)

sed不喜欢替换文字中的换行符。

$ sed 's~a~b~' /dev/null

$ sed 's~a~b
~' /dev/null
sed: -e expression #1, char 5: unterminated `s' command

它接受\n,因此您可以使用\n替换换行符。当然,你可以简单地在Perl中完成工作。这将有助于您解决许多其他问题:

  • Shell命令注入错误。
  • 替换文字中没有转义\
  • 缺乏检测和处理错误。

答案 1 :(得分:0)

感谢@ Beta的评论,我能够获得我想要的结果。它涉及:

  1. 更改子程序getstringforreplace()将qq()的内容打印到临时文件,
  2. 使用sed进行就地替换,将该文件的内容读入/etc/nginx/nginx.conf,
  3. 然后删除临时文件。
  4. ......以下是:

    getstringforreplace(); # Prints $replacement_string to temp.txt.
    my $command = qq ( sudo sed -i -e '/octet-stream;/r temp.txt' /etc/nginx/nginx.conf );
    system ( $command );
    system ( 'sudo rm temp.txt' );
    

    理想情况下,我希望不必打印到文件等,但目前这会产生所需的结果。