tcsh behält Zeilenumbrüche bei der Befehlsersetzung „…“ bei.

tcsh behält Zeilenumbrüche bei der Befehlsersetzung „…“ bei.

Also habe ich ein einfaches Skript geschrieben, um sh-Stil- export key=valueAnweisungen in csh-style setenv key valuefür zu konvertieren docker-machine env.

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

und es wird die folgende Ausgabe erzeugt

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`

In meinem .tcshrchabe ich dieses Skript an den Alias ​​gebunden docker-machine-env-csh.

Ich kann die Ausgabe dieses Skripts problemlos mit einer temporären Variable erstellen

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

Allerdings kann ich evaldas Ergebnis dieses Alias ​​nicht direkt

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

Oder weisen Sie es einer Variablen so zu, dass Zeilenumbrüche erhalten bleiben.

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

Allerdings printf "%s\n" `docker-machine-env-csh`scheint seltsamerweise zwischen jedem Token eine neue Zeile eingefügt zu werden.

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

Wie behalte ich Zeilenumbrüche bei tcshder Befehlsersetzung bei?

Antwort1

Es gibt viele gute Gründe, warum von der Verwendung von cshoder tcshfür Skripting abgeraten wird. Dies ist einer davon.

Um die Ausgabe von some commandverbatim in eine Shell-Variable in zu bekommen tcsh, benötigen Sie etwas wie:

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

Vergessen Sie nicht, $var:qzum Erweitern der Variable die folgende Syntax zu verwenden:

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

Das POSIX- shÄquivalent wäre:

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

Wenn Ihr docker-machine-env-cshBefehl die Informationen nun nur in einer Zeile ausgibt oder zumindest jede Zeile mit einem ;und ohne Kommentare abschließt, so dass sie auch bei Verbindung mit Leerzeichen gültiger CSH-Code sind (wie dies bei Anwendungen wie dircolorsoder der Fall ist, wenn ihre Ausgabe an 's ssh-agentübergeben werden soll ), können Sie Folgendes tun:csheval

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

Mit set var = `docker-machine-env-csh`wird tcshbei Leerzeichen geteilt (und eine Array-Variable erstellt), während mit set var = "`docker-machine-env-csh`"nur bei Zeilenumbrüchen geteilt wird (immer noch eine Array-Variable, aber wenn die Ausgabe nur eine Zeile hat, hat das Array nur ein Element).

Hier können Sie "$var"anstelle von verwenden $var:q, da $varkeine Zeilenumbruchzeichen enthalten sind. "$var"würde die Array-Elemente mit einem Leerzeichen verbinden, während $var:qsie beibehalten würde (hier gibt es nur ein Element, daher macht es keinen Unterschied). Wenn diese Array-Elemente Zeilenumbrüche enthalten könnten und Sie sie mit einem Leerzeichen verbinden möchten, würden Sie verwenden "$var:q".

Vielleicht können Sie Ihr Skript wie folgt ändern:

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

verwandte Informationen