我正在使用以下 bash 函数以彩色打印多行字符串。
desc="
Syp:
{-W,-w,--wht}
-f FILE
Print Syp brief
Red:
Some red details here.
Code:
Some code here
More code
Red:
Some red details here.
Blu:
Some blue details here.
Some blue details here.
Mgn:
Magonta
Cyn:
Some details here.
Code:
Code here
More code
Rst:
Wore"
fire "$desc"
Wht:
使用, Grn:
, Blu:
, Ylw:
, Red:
,时,事情按预期工作,Amb:
但使用和时则不然。我很难理解他们的行为有何不同。Cyn:
Mgn:
Syp:
Code:
Syp:
并Code:
接到 的电话!kl
。
fire ()
{
awk 'BEGIN { kl=0
("tput sgr0") |& getline rst
ka = "Wht 15 Grn 34 Blu 39 Ylw 11 Red 196 Amb 214"
kb = "Cyn 51 Mgn 201 Syp 196 Code 196"
ks = sprintf("%s %s", ka, kb)
n = split(ks, kaggr)
for ( i=1; i<n; i+=2 ) {
knam = kaggr[i] ":"
knum = kaggr[i+1]
("tput bold; tput setaf " knum) |& getline tseq[knam]
}
}
($1 in tseq) { kl=1 ; ctp=$1 ; next }
/Rst:/ { kl=0 ; next }
kl { printf("%s%s%s\n", tseq[ctp], $0, rst) }
!kl { printf("%s\n", $0) }
' <<< "$@"
}
答案1
第一次为颜色代码 196(对于 )调用 tput 时,您将生成一个协进程,Red
并且没有关闭它的管道,因此在接下来的 2 次您尝试对同一进程使用同一管道(对于Syp
和Code
)。正如我已经多次提到的:
- 不要为此使用协进程,因为您不需要这样做,
- 测试 getline 失败(如果你这样做了,你的代码就会向你报告这个问题),并且
- 一定要关闭您打开的管道。
另外 - 你不需要为此使用 3 个单独的变量:
ka = "Wht 15 Grn 34 Blu 39 Ylw 11 Red 196 Amb 214"
kb = "Cyn 51 Mgn 201 Syp 196 Code 196"
ks = sprintf("%s %s", ka, kb)
你可以这样做:
ks = "Wht 15 Grn 34 Blu 39 Ylw 11 Red 196 Amb 214 " \
"Cyn 51 Mgn 201 Syp 196 Code 196"
另外,这个:
kl { printf("%s%s%s\n", tseq[ctp], $0, rst) }
!kl { printf("%s\n", $0) }
只是:
kl { print tseq[ctp] $0 rst }
!kl { print }
所有这些都使您的代码不必要地复杂化[s]printf
。