Вам не нужно редактировать ваш ~ / .zshrc
.
Поскольку вы работаете с virtualenvwrapper
, можно добавить параметры или перехватчики в $ WORKON_HOME / post (de) activate
файлы.
Если вы хотите увидеть более подробную информацию, обратитесь к здесь .
Приведенная выше ссылка позволяет мне сделать следующее:
В моем случае $ WORKON_HOME = ~ / Envs
, потому что я изменил этот путь при установке virtualenvwrapper; в противном случае у вас должна быть папка ~ / .virtualenvs
.
Откройте файл postactivate
, расположенный в $ WORKON_HOME
Добавьте эти строки:
PS1 = "$ _ OLD_VIRTUAL_PS1"
_ OLD_RPROMPT = "$ RPROMPT" {{1 }} RPROMPT = "% {$ {fg_bold [белый]}%} (env:% {$ {fg [green]}%}` basename \ "$ VIRTUAL_ENV \" `% {$ {fg_bold [white]}%} )% {$ {reset_color}%} $ RPROMPT "
Сохраните и наслаждайтесь!
(НЕОБЯЗАТЕЛЬНО) Если хотите, вы можете отредактировать файл postdeactivate
, добавив эту строку:
RPROMPT = "$ _ OLD_RPROMPT"
Проблема в том, что в Bash внутри $ (...)
escape-последовательностей (и других) разбираются, даже если сам heredoc их не имеет. Вы получаете удвоенную строку, потому что \
экранирует разрыв строки. То, что вы видите, на самом деле является проблемой синтаксического анализа в Bash - другие оболочки этого не делают. Обратные кавычки также могут быть проблемой в старых версиях. Я подтвердил, что это ошибка в Bash , и она будет исправлена в будущих версиях.
Вы можете, по крайней мере, значительно упростить вашу функцию:
func() {
res=$(cat)
}
func <<'HEREDOC'
...
HEREDOC
Если вы хотите выбрать выходную переменную, ее можно параметризовать:
func() {
eval "$1"'=$(cat)'
}
func res<<'HEREDOC'
...
HEREDOC
Или довольно некрасивую без eval
:
{ res=$(cat) ; } <<'HEREDOC'
...
HEREDOC
Параметр {}
необходимы, а не ()
, чтобы переменная оставалась доступной впоследствии.
В зависимости от того, как часто вы будете это делать и с какой целью, вы можете предпочесть тот или иной из этих вариантов. Последний - самый лаконичный и разовый.
Если вы можете использовать zsh
, ваша исходная подстановка команд + heredoc будет работать как есть, но вы также можете свернуть все это дальше:
x=$(<<'EOT'
...
EOT
)
Bash не поддерживает это и я не думаю, что какая-либо другая оболочка, которая столкнется с вашей проблемой, тоже.
О решении OP:
Вам не нужен eval для присвоения переменной, если вы разрешаете использовать некоторую постоянную переменную.
Также может быть реализована общая структура вызова функции, которая принимает HEREDOC.
Решение, которое работает во всех (разумных) оболочках, когда оба пункта решены, следующее:
#!/bin/bash
nl="
"
read_heredoc(){
var=""
while IFS="$nl" read -r line; do
var="$var$line$nl"
done
}
read_heredoc <<'HEREDOC'
_ _ _
| | | (_)
_ __ ___ _ _ _ __ | | __ _ ___ ___ ___ _ __ | |_ _ __ ___
| '_ ` _ \| | | | '_ \| |/ _` |/ __/ _ \/ _ \| '_ \| | | '_ \ / _ \
| | | | | | |_| | |_) | | (_| | (_| __/ (_) | | | | | | | | | __/
|_| |_| |_|\__, | .__/|_|\__,_|\___\___|\___/|_| |_|_|_|_| |_|\___|
__/ | |
|___/|_|
HEREDOC
read_heredoc2_result="$str"
printf '%s' "${read_heredoc2_result}"
Решение, работающее с bash 2.04 (и недавних версий zsh, lksh, mksh).
Ниже вы найдете более портативную (POSIX) версию.
#!/bin/bash
read_heredoc() {
IFS='' read -d '' -r var <<'HEREDOC'
_ _ _
| | | (_)
_ __ ___ _ _ _ __ | | __ _ ___ ___ ___ _ __ | |_ _ __ ___
| '_ ` _ \| | | | '_ \| |/ _` |/ __/ _ \/ _ \| '_ \| | | '_ \ / _ \
| | | | | | |_| | |_) | | (_| | (_| __/ (_) | | | | | | | | | __/
|_| |_| |_|\__, | .__/|_|\__,_|\___\___|\___/|_| |_|_|_|_| |_|\___|
__/ | |
|___/|_|
HEREDOC
}
read_heredoc
echo "$var"
Основная команда
IFS='' read -d '' -r var <<'HEREDOC'
работает следующим образом:
HEREDOC
заключено в (одинарные) кавычки, чтобы избежать расширения текста, который следует за ним. <<
. -d ''
заставляет читать
, чтобы пропустить все содержимое «здесь документа». -r
позволяет избежать интерпретации символов в кавычках с обратной косой чертой. read var
. IFS = ''
, что позволит избежать чтения и удаления начальных или конечных символов в IFS по умолчанию: пробел табуляция новая строка . В ksh нулевое значение параметра -d ''
не работает.
В качестве временного решения, если в тексте нет «возврата каретки», работает -d $ '\ r'
(если $ '\ r'
, конечно же, добавляется в конец каждой строки).
Дополнительное (в комментариях) требование - создать решение, совместимое с POSIX.
Расширение идеи, позволяющей запускать только с параметрами POSIX.
В основном это означает отсутствие -d
для чтения
. Это заставляет читать каждую строку.
Это, в свою очередь, вызывает необходимость захватывать по очереди.
Затем для построения var
необходимо добавить завершающую новую строку (поскольку чтение удалило ее).
#!/bin/sh
nl='
'
read_heredoc() {
unset var
while IFS="$nl" read -r line; do
var="$var$line$nl"
done <<\HEREDOC
_ _ _
| | | (_)
_ __ ___ _ _ _ __ | | __ _ ___ ___ ___ _ __ | |_ _ __ ___
| '_ ` _ \| | | | '_ \| |/ _` |/ __/ _ \/ _ \| '_ \| | | '_ \ / _ \
| | | | | | |_| | |_) | | (_| | (_| __/ (_) | | | | | | | | | __/
|_| |_| |_|\__, | .__/|_|\__,_|\___\___|\___/|_| |_|_|_|_| |_|\___|
__/ | |
|___/|_|
HEREDOC
}
read_heredoc
printf '%s' "$var"
Это работает (и было протестировано) во всех разумных оболочках.
Чтобы поддерживать завершающие символы новой строки, я объединил ответ от @MichaelHomer и свое исходное решение. Я не использовал предлагаемые обходные пути из ссылки, которую отметил @EliahKagan, потому что первая использует магические строки, а последние две не соответствуют POSIX.
#!/bin/sh
NEWLINE="
"
read_heredoc() {
read_heredoc_result=""
while IFS="${NEWLINE}" read -r read_heredoc_line; do
read_heredoc_result="${read_heredoc_result}${read_heredoc_line}${NEWLINE}"
done
eval $1'=${read_heredoc_result}'
}
read_heredoc heredoc_str <<'HEREDOC'
_ _ _
| | | (_)
_ __ ___ _ _ _ __ | | __ _ ___ ___ ___ _ __ | |_ _ __ ___
| '_ ` _ \| | | | '_ \| |/ _` |/ __/ _ \/ _ \| '_ \| | | '_ \ / _ \
| | | | | | |_| | |_) | | (_| | (_| __/ (_) | | | | | | | | | __/
|_| |_| |_|\__, | .__/|_|\__,_|\___\___|\___/|_| |_|_|_|_| |_|\___|
__/ | |
|___/|_|
HEREDOC
echo "${heredoc_str}"
Бесполезное использование cat (цитата \ и `):
myplaceonline="
_ _ _
_ __ ___ _ _ _ __ | | __ _ ___ ___ ___ _ __ | (_)_ __ ___
| '_ \` _ \\| | | | '_ \\| |/ _\` |/ __/ _ \\/ _ \\| '_ \\| | | '_ \\ / _ \\
| | | | | | |_| | |_) | | (_| | (_| __/ (_) | | | | | | | | | __/
|_| |_| |_|\\__, | .__/|_|\\__,_|\\___\\___|\\___/|_| |_|_|_|_| |_|\\___|
|___/|_
"
Или без цитирования:
myplaceonline="$(figlet myplaceonline)"