Есть не одна проблема, видно по скрипту из ваших примеров:
#!/bin/sh
MSG="this is MAJOR stuff"
echo "$MSG" | sed -e 's/\(.*MAJOR.*\)/\o033[93m\1\o033[39m/'
echo "$MSG" | sed -e 's/\(.*MAJOR.*\)/\033[40;5;95;38;5;202\033[0m/'
echo "$MSG" | sed -e 's/\(.*MAJOR.*\)/\o033[40;5;95;38;5;202\o033[0m/'
echo "$MSG" | sed -e 's/\(.*MAJOR.*\)/\033[38;5;202\033[0m/'
который выдает (^[
- escape):
^[[93mthis is MAJOR stuff^[[39m
this is MAJOR stuff33[40;5;95;38;5;202this is MAJOR stuff33[0m
^[[40;5;95;38;5;202^[[0m
this is MAJOR stuff33[38;5;202this is MAJOR stuff33[0m
В первой строке, ^[[93m
- aixterm 16-color escape для установки желтого текста, а ^39m
сбрасывает текст к цветам терминала по умолчанию.
Вторая строка имеет проблемы с не завершенной последовательностью escape (которая начинает с установки фона на black=40, blink=5, 95=яркий пурпурный текст, затем 38 и 5 пытаются ввести 256-цветную последовательность - которая не завершается).
Третья строка является небольшой вариацией второй.
Основная проблема в том, что ваш sed
не выдает управляющий символ, если вы не выразите его как \o033
(что вы сделали в нескольких местах).
Во-вторых, вы неправильно заканчиваете побеги. Последняя m
является частью последовательности. Если последний символ отсутствует, вся последовательность может быть отброшена. Лучше всего прочитать документацию: Последовательности управления XTerm.
Кстати, ANSI никогда не документировал ничего больше 8 цветов, поэтому менее запутанно называть последовательности по оригинальной реализации (aixterm для 16-цветных, xterm для 256-цветных).
Если вы просто хотите, чтобы все строки с MAJOR были выделены оранжевым цветом, то (основываясь на комментариях) вы могли бы сделать так:
sed -e 's/^\(.*MAJOR.*\)$/\o033[48;5;95m\1\o033[m/'
Однако, код 5
менее широко поддерживается, чем 2
с использованием R/G/B, что-то вроде этого:
sed -e 's/^\(.*MAJOR.*\)$/\o033[48;2;128;128;0m\1\o033[m/'
(128-е - это только первая попытка - ваши вкусы могут варьироваться).
Further reading:
Ejecutar eso sudo -i echo $'line1\nline2'
bajo strace muestra que Bash comienza así:
9183 execve("/bin/bash", ["-bash", "--login", "-c", "echo line1\\\nline2\\\n"],...
Ahora, strace
presenta caracteres especiales con una barra invertida -cuando muestra las cadenas, por lo que lo que Bash realmente obtiene como argumento para -c
es echo line1[backslash][newline]line2[backslash][newline]
y para el shell, una barra invertida al final de una línea marca una línea de continuación y elimina la barra invertida y la nueva línea siguiente.
Sin -i
, sudo
ejecuta echo
directamente, sin atravesar el caparazón:
9189 execve("/bin/echo", ["echo", "line1\nline2\n"],...
Aquí, esa es una nueva línea literal que va a echo
, y echo
lo imprime debidamente.
La idea aquí debe ser que sudo
intente agregar una capa de escape de shell para acomodar el hecho de que sh -c
toma una única cadena , mientras que sudo
toma el comando como distinto argumentos.
Compare los siguientes casos:
sudo
escapa del espacio (este es solo el nombre del comando, ¡sin argumentos!):
$ sudo -i 'echo foo'
-bash: echo foo: command not found
sudo
escapa de la barra invertida, por lo que esto realmente funciona (Bash's echo
no procesa la barra invertida):
$ sudo -i echo 'foo\bar'
foo\bar
Lo mismo con una pestaña:
$ sudo -i echo $'foo\tbar'
foo bar
Aquí, no hay comillas adicionales en la barra invertida, por lo que Bash lo elimina mientras procesa la línea de comando de shell(b
no es un carácter especial para el shell,y no necesita cotización. Esto es básicamente lo mismo quebash -c 'echo foo"b"ar'
):
$ bash -c 'echo foo\bar'
foobar
El problema es que no se puede escapar de una nueva línea con una barra invertida, y sudo
no parece tener eso en cuenta.
En cualquier caso, citar problemas como este probablemente sea un poco más fácil si almacena los comandos que desea en un archivo y lo ejecuta como un script.
Podrías cambiar la estructura del comando:
echo "echo \"line1${n}line2${n}\"" | sudo -i bash -s
De esta manera sudo
no ve el argumento y por lo tanto no puede estropearlo.