Отображение команды sed перед её выполнением в Bash-скрипте

Вопрос или проблема

Мне нужен совет о том, как сделать так, чтобы каждая команда, которую я выполняю в Bash-скрипте, сначала отображалась, а затем выполнялась. Я создал простую функцию и последующую команду sed, чтобы раскомментировать строки в файле pacman.conf, но это не работает. В частности, я хочу раскомментировать эти две строки:

YC="\033[1;33m"
RC="\033[0m"

RCH() {
    echo -e "${YC}    $*${RC}"
    arch-chroot /mnt /bin/bash -c "$*" | sed 's/^/    /'
}

RCH sed '/^#\[multilib\]/s/^#//n;/^#Include/s/^#//' /etc/pacman.conf

#[multilib]
#Include ...

Вот что мне нужно:

  • Поиск строки, начинающейся с #[multilib]. Если найдена, раскомментировать ее.
  • Перейти к следующей строке и искать строку, начинающуюся с #Include. Если найдена, раскомментировать ее. Затем остановиться, без дальнейшего поиска или модификаций.

Это не полный ответ, но обратите внимание, что это…

/bin/bash -c "$*"

…не сделает то, что вам нужно. Давайте упростим вашу функцию RCH до:

RCH() {
  /bin/bash -c "$*"
}

Рассмотрите поведение, если мы сделаем что-то подобное:

RCH sed 's/hello world/goodnight moon' somefile.txt

Вы получите:

sed: -e expression #1, char 7: unterminated `s' command

И это потому, что вы отбрасываете токенизацию исходной команды. Вместо того чтобы передавать два аргумента команде sed (s/hello world/goodnight moon/ и somefile.txt), вы фактически выполняете команду без кавычек:

sed s/hello world/goodnight moon/ somefile.txt

Это четыре аргумента (s/hello, world/goodnight, moon/, somefile.txt), и это недопустимая команда. Это, конечно, искусственный пример, но очень легко столкнуться с ситуациями, когда это становится реальной проблемой.

Вы можете получить соответствующее поведение, если вместо этого напишите:

RCH() {
  bash -s -c '"$@"' -- "$@"
}

(-- просто является заполнительной переменной для $0, чтобы первый аргумент для RCH стал $1 в подоболочке.)

Это сохранит исходную токенизацию командной строки:

$ echo hello world > somefile.txt
$ RCH sed 's/hello world/goodnight moon/' somefile.txt
goodnight moon

Ответ или решение

Для того чтобы сделать так, чтобы каждая команда, выполняемая в Bash-скрипте, сначала отображалась, а затем выполнялась, вам необходимо изменить вашу функцию RCH. Ваша изначальная реализация не учитывает правильную обработку аргументов команды. Ниже представлен усовершенствованный пример функции, который решает вашу задачу.

Код функции

#!/bin/bash

YC="\033[1;33m"  # Цвет для вывода
RC="\033[0m"     # Сброс цвета

RCH() {
    echo -e "${YC}    $*${RC}"  # Отображение команды
    bash -c "$*"               # Выполнение команды
}

# Команда, которую необходимо выполнить
RCH sed -i '/^#\[multilib\]/s/^#//; /^#Include/s/^#//' /etc/pacman.conf

Объяснение

  1. Функция RCH:

    • В функции сначала отображается команда с помощью echo. Использование -e позволяет интерпретировать управляющие последовательности (например, цвета).
    • Затем команда выполняется с помощью bash -c "$*", где "$*" представляет собой все аргументы, переданные функции. Это сохраняет правильное разбиение по аргументам.
  2. Использование sed:

    • Опция -i в команде sed (как в данном случае) позволяет редактировать файл на месте.
    • Данный sed выполняет две подзаменки в одной команде:
      • Первая часть s/^#\[multilib\]/s/^#// – находит строку, начинающуюся с #[multilib] и убирает символ #.
      • Вторая часть ;/^#Include/s/^#// – находит строку, начинающуюся с #Include и также убирает #. Операции выполняются последовательно.
  3. Запуск функции:

    • При вызове RCH с заданной командой sed, сначала будет напечатана команда, а потом будет осуществлено её исполнение.

Примечания

  • Убедитесь, что у вас есть необходимые права для редактирования файла /etc/pacman.conf.
  • В этом коде RCH может быть использована для выполнения любых команд, что даёт вам гибкость при написании других скриптов.

Заключение

Следуя этой инструкции и использованию приведённого кода, вы сможете добиться того, чтобы команды отображались перед выполнением, что является полезной практикой, особенно при работе с файлами конфигурации и системными командами. Таким образом, отладка ваших скриптов станет более прозрачной, а также поможет избежать неожиданных результатов в процессе выполнения.

Оцените материал
Добавить комментарий

Капча загружается...