Вопрос или проблема
Мне нужен совет о том, как сделать так, чтобы каждая команда, которую я выполняю в 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
Объяснение
-
Функция
RCH
:- В функции сначала отображается команда с помощью
echo
. Использование-e
позволяет интерпретировать управляющие последовательности (например, цвета). - Затем команда выполняется с помощью
bash -c "$*"
, где"$*"
представляет собой все аргументы, переданные функции. Это сохраняет правильное разбиение по аргументам.
- В функции сначала отображается команда с помощью
-
Использование
sed
:- Опция
-i
в командеsed
(как в данном случае) позволяет редактировать файл на месте. - Данный
sed
выполняет две подзаменки в одной команде:- Первая часть
s/^#\[multilib\]/s/^#//
– находит строку, начинающуюся с#[multilib]
и убирает символ#
. - Вторая часть
;/^#Include/s/^#//
– находит строку, начинающуюся с#Include
и также убирает#
. Операции выполняются последовательно.
- Первая часть
- Опция
-
Запуск функции:
- При вызове
RCH
с заданной командойsed
, сначала будет напечатана команда, а потом будет осуществлено её исполнение.
- При вызове
Примечания
- Убедитесь, что у вас есть необходимые права для редактирования файла
/etc/pacman.conf
. - В этом коде
RCH
может быть использована для выполнения любых команд, что даёт вам гибкость при написании других скриптов.
Заключение
Следуя этой инструкции и использованию приведённого кода, вы сможете добиться того, чтобы команды отображались перед выполнением, что является полезной практикой, особенно при работе с файлами конфигурации и системными командами. Таким образом, отладка ваших скриптов станет более прозрачной, а также поможет избежать неожиданных результатов в процессе выполнения.