1

Я пытаюсь написать командную оболочку bash, которая будет на лету исправлять текущую команду bash. Но я столкнулся с проблемой. Поскольку я не хороший пользователь Shell, я не могу написать правильное выражение назначения переменной в строке. Смотрите ниже:

Я установил trap для предварительного выполнения, через это:

 alex@bender:~$ trap "caller >/dev/null ||  xxx \"\${BASH_COMMAND}"\"  DEBUG;

Я хочу изменить переменную BASH_COMMAND, сделать что-то вроде BASH_COMMAND = xxx ${BASH_COMMAND} но я не знаю, как мне нужно экранировать переменные в этой строке

ПРИМЕЧАНИЕ: xxx - моя пользовательская функция, которая должна возвращать какое-то значение, если в конце команды находится слово teststr

function xxx(){
# find by grep, if teststr in the end
`echo "$1" | grep "teststr$" >/dev/null`;
# if true ==> do
if [ "$?" == "0" ]; then
    # cut last 6 chars (len('teststr')==6)
    var=`echo "$1" | sed 's/......$//'`;
    echo "$var";
fi    }

Как я могу сделать это ?:

alex@bender:~$ trap "caller >/dev/null || ${BASH_COMMAND}=`xxx $BASH_COMMAND`"  DEBUG;

1 ответ1

2

Вот возможное решение, но оно будет перехватывать все команды, а не только те, которые были введены через приглашение (поэтому команды в скриптах также будут перехвачены). Возможно, вам придется изменить его, чтобы получить то, что вы хотите.

Сначала установите параметр shopt extdebug .

Из руководства:

Если установлено, поведение, предназначенное для использования отладчиками, включено:

1- Опция -F встроенной функции объявления (см. Встроенные команды Bash) отображает имя исходного файла и номер строки, соответствующие имени каждой функции, предоставленной в качестве аргумента.
2- Если команда, запускаемая ловушкой DEBUG, возвращает ненулевое значение, следующая команда пропускается и не выполняется.
3- Если команда, запускаемая ловушкой DEBUG, возвращает значение 2, а оболочка выполняется в подпрограмме (функция оболочки или сценарий оболочки, выполняемый встроенными командами. Или source), имитируется вызов return.
4- BASH_ARGC и BASH_ARGV обновляются, как описано в их описаниях (см. Переменные Bash).
5- Включена трассировка функций: подстановка команд, функции оболочки и подоболочки, вызванные (команда), наследуют ловушки DEBUG и RETURN.
6- Включена трассировка ошибок: подстановка команд, функции оболочки и подоболочки, вызванные (команда), наследуют ловушку ERR.

(акцент мой)

Вам нужна эта команда, чтобы отменить выполнение команды, введенной пользователем, и вместо этого вызвать вашу пользовательскую функцию. Если это не установлено, Bash вызовет вашу пользовательскую функцию и выполнит команду пользователя.

Затем используйте простые кавычки, чтобы написать ловушку, чтобы предотвратить расширение переменной Bash:

trap 'caller >/dev/null || xxx $BASH_COMMAND' DEBUG

Теперь, если ваша функция xxx возвращает ненулевое значение (например, 1), команда пользователя не будет выполнена.


Вот полный пример:

$ shopt -s extdebug
$ xxx() { if [ "$1" = 'sudo' ]; then echo "No sudo, please.";return 1; fi }
$ trap 'caller >/dev/null || xxx $BASH_COMMAND' DEBUG
$ ls
foo bar
$ sudo ls
No sudo, please.

В этом примере xxx проверяет, является ли первое слово команды sudo , и если да, печатает сообщение и отменяет команду. Вы можете получить всю пользовательскую команду в xxx , используя "$*" .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .