Итак, я написал простой скрипт для преобразования операторов sh
в стиле for .export key=value
csh-style
setenv key value
docker-machine env
#!/bin/sh
docker-machine env | sed -e 's/export/setenv/' -e 's/=/ /' -e '$d'
echo '# eval `docker-machine env`'
и он выдает следующий вывод
setenv DOCKER_TLS_VERIFY "1"
setenv DOCKER_HOST "tcp://<ipv4 address>:<port>"
setenv DOCKER_CERT_PATH "<HOME>/.docker/machine/machines/default"
setenv DOCKER_MACHINE_NAME "default"
# Run this command to configure your shell:
# eval `docker-machine env`
В моем случае .tcshrc
я привязал этот скрипт к псевдониму docker-machine-env-csh
.
Я могу получить вывод этого скрипта, используя временную переменную, и это нормально.
% docker-machine-env-csh >! /tmp/csh && source /tmp/csh
Однако, похоже, я не могу напрямую определить eval
результат этого псевдонима.
% eval `docker-machine-env-csh`
setenv: Too many arguments.
Или присвойте его переменной таким образом, чтобы сохранялись переносы строк.
% set a = `docker-machine-env-csh`
% printf "%s\n" "$a"
setenv ... setenv ... setenv ...
Хотя, как ни странно, printf "%s\n" `docker-machine-env-csh`
между каждым токеном вставляется новая строка.
% printf "%s\n" `docker-machine-env-csh`
setenv
...
...
setenv
...
...
Как сохранить переводы строк при tcsh
подстановке команд?
решение1
Есть много веских причин, по которым не рекомендуется использовать csh
или tcsh
для скриптов. Это одна из них.
Чтобы перенести вывод some command
verbatim в переменную оболочки в tcsh
, вам нужно что-то вроде:
set temp = "`(some command; echo .) | paste -d . - /dev/null`"
set var = ""
set nl = '\
'
foreach i ($temp:q)
set var = $var:q$i:r:q$nl:q
end
set var = $var:r:q
Не забудьте использовать $var:q
синтаксис для расширения переменной, как в:
printf '<%s>\n' $var:q
Эквивалент POSIX sh
будет следующим:
var=$(some command; echo .)
var=${var%.}
Теперь, если ваша docker-machine-env-csh
команда выводит информацию только в одну строку или, по крайней мере, каждая строка заканчивается символом a ;
и без комментариев, так что при объединении пробелами они по-прежнему остаются допустимым кодом csh (как это делают такие приложения, как dircolors
или , ssh-agent
когда хотят, чтобы их вывод был передан в csh
' s eval
), то вы можете сделать следующее:
set var = "`docker-machine-env-csh`"
printf '%s\n' "$var"
# or printf '%s\n' $var:q
# or printf '%s\n' "$var:q"
При использовании set var = `docker-machine-env-csh`
происходит tcsh
разбиение по пробелам (и создается переменная массива), тогда как при использовании set var = "`docker-machine-env-csh`"
происходит разбиение только по новой строке (все еще переменная массива, но если вывод содержит только одну строку, этот массив содержит только один элемент).
Здесь вы можете использовать "$var"
вместо $var:q
потому что $var
не содержит символов новой строки. "$var"
объединит элементы массива пробелом, в то время как $var:q
сохранит их (здесь только один элемент, так что это не имеет значения). Если эти элементы массива могут содержать новые строки и вы хотите объединить их пробелом, вы должны использовать "$var:q"
.
Так что, возможно, вы можете изменить свой сценарий следующим образом:
#! /bin/sh -
docker-machine env | sed '
s/export/setenv/
s/=/ /
/^#/!s/$/;/
$d'
echo '# eval "`docker-machine env`"'