Почему eval "$ BASH_COMMAND" аварийно завершает работу bash? - PullRequest
1 голос
/ 13 марта 2019

Если вы запустите eval "$BASH_COMMAND" в терминале, он вылетит и окно терминала исчезнет.Я не смог понять, почему эта конкретная команда дает сбой bash.

Странно то, что когда я запускаю echo "$BASH_COMMAND", это происходит:

$ echo "$BASH_COMMAND"
echo "$BASH_COMMAND"

Другое дело, что$BASH_COMMAND не имеет значения:

"$BASH_COMMAND"
bash: "$BASH_COMMAND": command not found

1 Ответ

3 голосов
/ 13 марта 2019

$BASH_COMMAND имеет значение: текущая команда выполняется.Это полезно в таких ситуациях, как обработчик trap, поэтому обработчик может узнать, какая команда выполнялась при срабатывании ловушки.Но когда вы используете $BASH_COMMAND как часть обычной команды, все становится странным, круговым и запутанным.Давайте рассмотрим примеры, которые вы дали:

  • echo "$BASH_COMMAND"

    В этом примере значением переменной BASH_COMMAND является в точности строка echo "$BASH_COMMAND", поэтомукогда оболочка анализирует командную строку, она расширяет ссылку на переменную, давая эквивалент:

    echo 'echo "$BASH_COMMAND"'
    

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

  • "$BASH_COMMAND"

    Опять же, значение BASH_COMMAND - это точнострока "$BASH_COMMAND", поэтому после раскрытия она эквивалентна:

    '"$BASH_COMMAND"'
    

    ... и команды с таким именем не существует, поэтому вы получите ошибку с таким эффектом.

    (На самом деле, кавычки и знаки доллара допускаются в именах файлов Unix, так что вы можете назвать скрипт, который поместит его где-нибудь в вашем PATH, и тогда будет допустимым именем команды. Я неособенно рекомендую это делать.)

  • eval "$BASH_COMMAND"

    Этот более сложный.Значение BASH_COMMAND - это строка eval "$BASH_COMMAND", поэтому после раскрытия она эквивалентна:

    eval 'eval "$BASH_COMMAND"'
    

    Но команда eval принимает свой аргумент и запускает его как команду оболочки,включая все обычные разборы.Таким образом, он запускает команду:

    eval "$BASH_COMMAND"
    

    ..., которая снова расширяет $BASH_COMMAND, что приводит к:

    eval 'eval "$BASH_COMMAND"'
    

    ..., что делает синтаксический анализ команды eval изапустите:

    eval "$BASH_COMMAND"
    

    ... и этот цикл продолжается вечно.Или, скорее, в конечном итоге он исчерпывает какой-то ресурс (возможно, место в стеке), поскольку он пытается отслеживать эту постоянно расширяющуюся вещь.Очевидно, это приводит к неудачному сбою.

    Но каковы бы ни были детали, эта команда не может работать.Он просит оболочку выполнить бесконечный ряд задач, и это не может успешно завершиться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...