Also habe ich ein einfaches Skript geschrieben, um sh
-Stil- export key=value
Anweisungen in csh-style
setenv key value
fü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 .tcshrc
habe 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 eval
das 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 tcsh
der Befehlsersetzung bei?
Antwort1
Es gibt viele gute Gründe, warum von der Verwendung von csh
oder tcsh
für Skripting abgeraten wird. Dies ist einer davon.
Um die Ausgabe von some command
verbatim 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:q
zum 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-csh
Befehl 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 dircolors
oder der Fall ist, wenn ihre Ausgabe an 's ssh-agent
übergeben werden soll ), können Sie Folgendes tun:csh
eval
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 tcsh
bei 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 $var
keine Zeilenumbruchzeichen enthalten sind. "$var"
würde die Array-Elemente mit einem Leerzeichen verbinden, während $var:q
sie 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`"'