tcsh preserva nuevas líneas en la sustitución de comandos `...`

tcsh preserva nuevas líneas en la sustitución de comandos `...`

Entonces, escribí un script simple para convertir declaraciones shde estilo a 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`'

y produce el siguiente resultado

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`

En mi caso, .tcshrche vinculado este script al alias docker-machine-env-csh.

Puedo obtener el resultado de este script usando una variable temporal muy bien.

% docker-machine-env-csh >! /tmp/csh && source /tmp/csh

Sin embargo, parece que no puedo acceder directamente evalal resultado de este alias.

% eval `docker-machine-env-csh`
setenv: Too many arguments.

O asígnelo a una variable de manera que conserve las nuevas líneas.

% set a = `docker-machine-env-csh`
% printf "%s\n" "$a"
setenv ... setenv ... setenv ...

Aunque, extrañamente printf "%s\n" `docker-machine-env-csh`parece insertar una nueva línea entre cada token.

% printf "%s\n" `docker-machine-env-csh`
setenv
...
...
setenv
...
...

¿Cómo conservo las nuevas líneas en tcshla sustitución de comandos?

Respuesta1

Hay muchas buenas razones por las que se recomienda no utilizar csho tcshpara secuencias de comandos. Ese es uno de esos.

Para obtener la salida some commandtextual en una variable de shell en tcsh, necesita 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

No olvides usar $var:qla sintaxis para expandir la variable como en:

printf '<%s>\n' $var:q

El shequivalente POSIX sería:

var=$(some command; echo .)
var=${var%.}

Ahora, si su docker-machine-env-cshcomando generó la información en una sola línea, o al menos con cada línea terminada con ;y sin comentarios para que cuando se unan con espacios sigan siendo código csh válido (como aplicaciones como dircolorso ssh-agentcuando quieren su salida para pasar a csh's eval), entonces podrías hacer:

set var = "`docker-machine-env-csh`"
printf '%s\n' "$var"
# or printf '%s\n' $var:q
# or printf '%s\n' "$var:q"

Con set var = `docker-machine-env-csh`, tcshse divide en espacios en blanco (y crea una variable de matriz), mientras que con set var = "`docker-machine-env-csh`", se divide solo en nueva línea (sigue siendo una variable de matriz, pero si la salida tiene solo una línea, esa matriz tiene solo un elemento).

Aquí puede utilizar "$var"en lugar de $var:qporque $varno contiene caracteres de nueva línea. "$var"uniría los elementos de la matriz con espacio mientras $var:qlos preservaría (aquí solo hay un elemento, por lo que no hay diferencia). Si esos elementos de la matriz pueden contener nuevas líneas y desea unirlos con espacio, usaría "$var:q".

Entonces tal vez puedas modificar tu script como:

#! /bin/sh -
docker-machine env | sed '
  s/export/setenv/
  s/=/ /
  /^#/!s/$/;/
  $d'
echo '# eval "`docker-machine env`"'

información relacionada