He estado luchando con esto durante más de una hora y no estoy seguro de qué pasa. Usando Perl, estoy tratando de usar sed para hacer un reemplazo en línea de una cadena en /etc/nginx/nginx.conf como se indica usando el comando sed a continuación:

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.

Realmente estoy tratando de colocar $ replacement_string después de hacer coincidir esa línea de 'tipo predeterminado' en nginx.conf, pero no estoy seguro de qué usar además de sed.

(1) cambié los delimitadores para evitar problemas con las barras diagonales, (2) cité dos veces el reemplazo (realmente no estoy seguro de por qué, estaba usando comillas simples antes) y (3) eliminé un carácter de nueva línea Tenía justo antes de $ replacement_string, entre otras cosas.

Seguí adelante y puse el die ($ command); allí como se indica en this respuesta, pero no veo lo que está mal. Esto es lo que devuelve, que es más o menos lo que quiero:

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 es devuelto por la llamada a la subrutina getstringforreplace () a continuación:

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;
}

Cualquier orientación sería muy apreciada ya que no estoy seguro de cómo deshacerme de este problema de comando `s 'sin terminar . Estoy pensando que ahora tiene que ver con qq () de la subrutina que estoy llamando.

0
René Alejandro Santiago 19 feb. 2018 a las 08:52

2 respuestas

La mejor respuesta

Gracias a los comentarios de @ Beta anteriores, pude obtener el resultado que quería. Implicaba:

  1. cambiando la subrutina getstringforreplace () para imprimir el contenido de qq () en un archivo temporal,
  2. haciendo un reemplazo en el lugar usando sed para leer el contenido de ese archivo en /etc/nginx/nginx.conf,
  3. y luego eliminar el archivo temporal.

... que está abajo:

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' );

Idealmente, me hubiera gustado no tener que imprimir en un archivo, etc., pero por el momento esto produce el resultado deseado.

0
René Alejandro Santiago 20 feb. 2018 a las 00:57

A sed no le gustan las líneas nuevas en el literal de reemplazo.

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

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

Acepta \n, por lo que podría reemplazar las líneas nuevas con \n. Por supuesto, podría simplemente hacer el trabajo en Perl. Esto lo ayudará a abordar una serie de otros problemas:

  • Error de inyección de comandos de shell.
  • Falta de escape \ en el literal de reemplazo.
  • Falta de detección y manejo de errores.
1
ikegami 19 feb. 2018 a las 06:21