Tcsh

tcsh 在命令替換中保留換行符...

  • August 29, 2020

因此,我編寫了一個簡單的腳本來將sh-styleexport key=value語句轉換為csh-style setenv key valuefor docker-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我已經將此腳本綁定到 alias 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命令替換中保留換行符?

有很多充分的理由建議不要使用cshtcsh編寫腳本。那就是其中之一。

要將some command逐字輸出到 shell 變數中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

POSIXsh等價物是:

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

現在,如果您的docker-machine-env-csh命令確實只在一行上輸出了資訊,或者至少每行都以 a 結尾;並且沒有註釋,那麼當與空格連接時,它們仍然是有效的 csh 程式碼(例如應用程序,例如dircolorsssh-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`"'

引用自:https://unix.stackexchange.com/questions/284220