Ваша проблема связана не с оболочкой или документом здесь, а с тем, что Expect использует $def
как ссылку на переменную и пытается расширить ее.
Здесь bar
— это переменная, установленная в Expect и раскрытая там (это одинарные -кавычки, оболочка не раскрывается$bar
):
$ expect -f - <<< 'set bar abcdefg; send_user "foo$bar\n"'
fooabcdefg
Это дает ту же ошибку, которую вы видели (сценарий ожидания дважды -заключен в кавычки, поэтому$var
расширяется в оболочке, в отличие от предыдущего):
$ var='foo$bar'; expect -f - <<< "send_user \"$var\n\""
can't read "bar": no such variable
while executing
"send_user 'foo$bar\n'"
Вам нужно экранировать $
, но тогда вам нужно будет экранировать по крайней мере [
также, так как это также особенное в Expect, или, скорее, в Tcl, на котором Expect построен. Может есть и другие, я не уверен...
Возможно, будет проще передать значение через аргумент командной строки.:
$ var='foo$bar[quux]'
$ expect -f - "$var" <<< 'set var [lindex $argv 0]; send_user "$var\n"'
foo$bar[quux]
Или через окружающую среду:
$ export var
$ expect -f - "$var" <<< 'set var $::env(var); send_user "$var\n"'
foo$bar[quux]
Немного ближе к тому, что делает ваш код:
#!/bin/bash
line='2.3.4.5:abc$def'
IFS=: read host pw <<< "$line"
export host pw
expect -f - << 'EOF'
set host $::env(host)
set pw $::env(pw)
send_user "host is '$host' pw is '$pw'\n"
EOF
С помощью переменных, передаваемых через среду, вы можете сделать здесь -документ в кавычках, чтобы оболочка не расширяла $
s, и использовать переменные Expect $host
и $pw
там, где это необходимо.
Вам нужно бежать
eval "$(pip completion --zsh)"
Сравните вывод этих двух команд:
echo $(pip completion --zsh)
echo "$(pip completion --zsh)"
В zsh $VARIABLE
означает «брать значение VARIABLE
, если оно не пусто». Но $(command)
означает «взять вывод command
и разбить его на слова по пробелам». Так, в eval $(pip completion --zsh)
все последовательности пробелов, включая символы новой строки, рассматриваются как разделители слов. Затем eval
объединяет все свои аргументы с пробелом между ними. Но пробел не эквивалентен новой строке, и код, который выполняется eval
, представляет собой всего лишь одну длинную строку комментария.
Это подмножество Почему мой сценарий оболочки забивается пробелами или другими специальными символами?:в zsh, в отличие от других sh -подобных оболочек, разделение слов происходит только при подстановке команд, а не при подстановке переменных (, за исключением ограниченной формы, когда пустое слово, полученное в результате подстановки переменных, удаляется ), и в результате расширения автоматически не происходит подстановки. Вам нужны двойные кавычки в zsh вокруг подстановки команд и подстановки переменных, когда это может привести к пустому слову.