eepm icon indicating copy to clipboard operation
eepm copied to clipboard

Escaping special Shell characters in `showcmd()`.

Open eteryear opened this issue 2 months ago • 4 comments

Continuation of issue https://github.com/Etersoft/eepm/issues/507.

Such escaping should work on all POSIX Shells. With Bash extensions, one can create much more simple solution, like this:

# Print command line and run command line
docmd()
{
    showcmd "$(echo $* | xargs -n1 printf '%q ' | sed -e 's/ $//1')$EXTRA_SHOWDOCMD"
    "$@"
}

eteryear avatar Oct 27 '25 20:10 eteryear

Зачем нужно что-то экранировать?

vitlav avatar Nov 03 '25 07:11 vitlav

Зачем нужно что-то экранировать?

EEPM выводит неверную информацию при попытке поиска по регулярным выражениям. Так, например, epms "media|video" player печатает строку, которая передаёт вывод apt-cache search -- media в несуществующую команду video:

apt-cache search -- media|video | grep -E -i -- "media|video" | grep -E -i -- "player" | grep -E -i --color -- "(media|video|player)"

Подробнее см. #507. Регулярными выражениями пользуюсь часто, поэтому казалось естественным использовать их и в EEPM.

eteryear avatar Nov 05 '25 09:11 eteryear

Вопреки теме MR, исправляется не функция showcmd. Написано, что экранируются специальные символы, а на деле экранируется всё, кроме. Также всё это слишком громоздко выглядит.

vitlav avatar Nov 12 '25 20:11 vitlav

Вопреки теме MR, исправляется не функция showcmd.

Да, действительно, проглядел, что уже не ту функцию правлю. В showcmd() на момент получения входной строки ничего сделать нельзя — все аргументы в docmd() уже оказываются слеплены в один большой аргумент.

Написано, что экранируются специальные символы, а на деле экранируется всё, кроме.

Мне кажется, вот так оно выглядит куда хуже:

case "$INPUT" in
    *[\`\!\$\^\&\*\(\)\{\}\|\[\]\\\;\'\",\<\>?\#]*)
        # Escape args containing special characters.

Также всё это слишком громоздко выглядит.

Как говорил, это необходимо, если придерживаться стандартов совместимости POSIX. Если ограничиться конкретной оболочкой — можно ужать до одной строки.

Впрочем, можно сделать три вещи:

  1. Убрать перестраховку "[ -z "$INPUT" ] && echo "''" && return", так как пустой аргумент теоретически передаться в текущей системе не может.
  2. Удалить обработку обратных слэшей, так как в EEPM-запрос их вставить не удаётся, они где-то по пути до docmd() обязательно теряются. Но вот apt-cache search -- '\\' работает исправно, так что, возможно, позже нужно будет в выражение экранирования вернуть.
  3. Поправить основную экранирующую последовательность. Заметил, что почти во всём проекте в качестве разделителя используется не более классический '/', а '|' (предполагаю, потому, что часто идёт работа с путями) — так что заметил на него.
echon "$INPUT" | sed  -e "s|'|'\"'\"'|g"  -e "s|.\+|'&' |g"

В целом всё то же самое: сначала экранируются одинарные кавычки, затем вход оборачивается в них же. Но на этой неделе я случайно узнал про символ '&' в sed, так что последнее выражение стало чуть короче.

eteryear avatar Nov 13 '25 09:11 eteryear