tcsh сохраняет переводы строк при замене команд `...`

tcsh сохраняет переводы строк при замене команд `...`

Итак, я написал простой скрипт для преобразования операторов shв стиле for .export key=valuecsh-style setenv key valuedocker-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 commandverbatim в переменную оболочки в 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`"'

Связанный контент