Ошибка Heredoc в подфункции экспортируемой функции

Вот несколько возможных вариантов.

  1. Не используйте tput, если у вас нет сеанса интерактивного терминала. Вы можете выбрать любой из этих подходов:

    [[ -t 1 ]] && tput setaf 2...          # Only set a colour if we have a tty
    
    [[ -n "$TERM" ]] && tput setaf 2...    # Only set a colour if we have a terminal type definition
    
  2. Установите тип фиктивного терминала. Вы можете export TERM=dumbотключить большинство функций terminfo/ termcap. Очевидно, вы захотите выполнить это только в том случае, если тип терминала еще не установлен:

    [[ -z "$TERM" ]] && export TERM=dumb    # Set a dummy terminal type if none set
    
    [[ ! -t 1 ]] && export TERM=dumb        # Set a dummy terminal type unless a tty
    

    При таком подходе вам не нужно изменять какой-либо последующий код; вы даже можете установить его перед запуском приложения, и ему не нужно будет знать никакой разницы.

4
25.03.2021, 13:46
1 ответ

Это ошибка, о которой впервые сообщили в июле 2019 года, см.:

Также есть вопрос по SO с очень похожим тестовым примером (, на который ссылается последнее письмо выше):Экспорт функции с вложенным определением функции и heredoc в bash

В файле CHANGES это указано между bash -5.0 -выпуском и bash -5.1 -alpha:

ll. Fixed a bug with printing function definitions containing here documents.

Насколько я проверял, ваш тестовый пример работает в Bash 4.4 и в текущей версии git.


Что мне показалось здесь любопытным, так это то, что если вы посмотрите на declare -p -f fooпосле того, как функция определена, вы увидите, что здесь -doc находится вне gen, чего не происходит, если true. Похоже, что-то там напутано. Это рабочая версия:

$ declare -p -f foo
foo () 
{ 
    function gen () 
    { 
        cat 
    } <<EOF
bar
EOF

    gen
}

А это сломанный:

$ declare -p -f foo
foo ()
{   
    function gen ()
    {   
        cat <<EOF
    }
bar
EOF 

    gen
}

Обратите внимание, что перенаправление << EOFнаходится в неправильном месте. закрытие }. Версия git помещает перенаправление туда, где оно было фактически размещено, так же, как это делают Ksh и Zsh.

5
28.04.2021, 22:56

Теги

Похожие вопросы