Então, escrevi um script simples para converter instruções sh
-style em 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`'
e produz a seguinte saída
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`
No meu, .tcshrc
vinculei esse script ao alias docker-machine-env-csh
.
Posso obter a saída deste script usando uma variável temporária perfeitamente
% docker-machine-env-csh >! /tmp/csh && source /tmp/csh
No entanto, não consigo entender diretamente eval
o resultado desse alias
% eval `docker-machine-env-csh`
setenv: Too many arguments.
Ou atribua-o a uma variável de uma forma que preserve as novas linhas.
% set a = `docker-machine-env-csh`
% printf "%s\n" "$a"
setenv ... setenv ... setenv ...
Embora, estranhamente, printf "%s\n" `docker-machine-env-csh`
pareça inserir uma nova linha entre cada token.
% printf "%s\n" `docker-machine-env-csh`
setenv
...
...
setenv
...
...
Como preservo novas linhas na tcsh
substituição de comandos?
Responder1
Existem muitos bons motivos pelos quais é recomendado não usar csh
ou tcsh
para scripts. Esse é um desses.
Para obter a saída some command
literal em uma variável shell tcsh
, você precisa de algo como:
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
Não se esqueça de usar $var:q
a sintaxe para expandir a variável como em:
printf '<%s>\n' $var:q
O equivalente POSIX sh
seria:
var=$(some command; echo .)
var=${var%.}
Agora, se o seu docker-machine-env-csh
comando produziu as informações em apenas uma linha, ou pelo menos com cada linha terminada com um ;
e sem comentários para que quando unidos com espaços eles ainda sejam códigos csh válidos (como aplicativos como dircolors
ou ssh-agent
fazem quando desejam sua saída a ser passado para csh
's eval
), então você poderia fazer:
set var = "`docker-machine-env-csh`"
printf '%s\n' "$var"
# or printf '%s\n' $var:q
# or printf '%s\n' "$var:q"
Com set var = `docker-machine-env-csh`
, tcsh
divide-se em espaços em branco (e cria uma variável de matriz), enquanto com set var = "`docker-machine-env-csh`"
, ele divide apenas em nova linha (ainda uma variável de matriz, mas se a saída tiver apenas uma linha, essa matriz terá apenas um elemento).
Aqui você pode usar "$var"
no lugar de $var:q
porque $var
não contém caracteres de nova linha. "$var"
juntaria os elementos do array com espaço enquanto $var:q
os preservaria (aqui há apenas um elemento, então não faz diferença). Se esses elementos da matriz puderem conter novas linhas e você quiser juntá-los com espaço, você usaria "$var:q"
.
Então talvez você possa modificar seu script como:
#! /bin/sh -
docker-machine env | sed '
s/export/setenv/
s/=/ /
/^#/!s/$/;/
$d'
echo '# eval "`docker-machine env`"'