Bash

是否可以在不影響 printf 的“%*s”填充格式的情況下更改終端中的字型顏色?

  • March 26, 2017

我在 bash 腳本中有一個函式:message_offset用於列印 bash 腳本的狀態。

即,您可以將其稱為向其中傳遞消息和狀態,如下所示

message_offset "install font library" "[   OK   ]" 

它會列印到終端,其中printf%*s格式用於始終將最右邊的字元設置[ OK ]為 80 列寬,例如輸出將是

install font library                              [   OK   ]
update configuration file on server               [   ERR  ]
                                                          ^
                                                          |
                                                     always
                                                       at 80

如果echo使用輸出將如下所示

install font library                 [   OK   ]
update configuration file on server               [   ERR  ]

程式碼:

#!/usr/bin/env bash

function message_offset() {

   local message="$1"
   local status="$2"

   # compensate for the message length by reducing the offset 
   # by the length of the message, 
   (( offset = 80 - ${#message} ))

   # add a $(tput sgr0) to the end to "exit attributes" whether a color was
   # set or not
   printf "%s%*s%s" "${message}" 80 "$status" "$(tput sgr0)"

}

這一切正常,直到我嘗試使用tput將一些顏色序列添加到字元串中,即製作“

$$ ERR $$“紅色。

似乎printf "%*s"格式化在設置偏移量時計算 tput 字元序列,所以如果我這樣呼叫函式

message_offset "update configuration file on server"  "$(tput setaf 1)[   ERR  ]"

輸出將類似於:

install font library                              [   OK   ]
update configuration file on server          [   ERR  ]

因為printf "%*s"是說嘿這個字元串已經得到了所有的"[ ERR ]"字元,加上"$(tput setaf 1)字元,但顯然"$(tput setaf 1)字元沒有列印出來,所以實際上不影響填充。

有沒有辦法可以為“狀態”消息添加顏色,並使用tput樣式顏色序列?

你讓這比它應該的複雜得多。您可以處理對齊$message而不關心 ANSI 序列的寬度:

#! /usr/bin/env bash

message() {
   [ x"$2" = xOK ] && color=2 || color=1
   let offset=$(tput cols)-4-${#2}
   printf "%-*s[ %s%s%s ]\n" $offset "$1" "$(tput setaf "$color")"  "$2" "$(tput sgr0)"
}  

message "install font library" "OK"
message "update configuration file on server" "ERR"

**編輯:**請注意,大多數printf(1)實現不能很好地處理多字節字元集的長度計算。因此,如果您想在 UTF-8 中列印帶有重音字元的消息,您可能需要一種不同的方法。聳聳肩

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