Ole Lukøje Asked:2020-07-29 04:05:20 +0000 UTC2020-07-29 04:05:20 +0000 UTC 2020-07-29 04:05:20 +0000 UTC 使用 Unicode Box Drawing 中的字符在 bash 中构建框架 772 我想以某种方式安排 Bashevsky 脚本,以便它在一个漂亮的框架中给出一个菜单。我在谷歌上搜索,抓挠我的萝卜,嗯,然后冲掉了几个小功能。结果,我很高兴地与 SO 参与者分享,突然间它会派上用场。 linux 1 个回答 Voted Best Answer Ole Lukøje 2020-08-01T00:31:00Z2020-08-01T00:31:00Z 这是发生的事情: declare -A C # Массив значений цветов def_colors () { C[Black]='\e[30m' C[Red]='\e[31m' C[Green]='\e[32m' C[Yellow]='\e[33m' C[Blue]='\e[34m' C[Magenta]='\e[35m' C[Cyan]='\e[36m' C[LGray]='\e[37m' C[Default]='\e[39m' C[DGray]='\e[90m' C[LRed]='\e[91m' C[LGreen]='\e[92m' C[LYellow]='\e[93m' C[LBlue]='\e[94m' C[LMagenta]='\e[95m' C[LCyan]='\e[96m' C[White]='\e[97m' C[Normal]='\e[0m' } draw_line () { local position="$1" local width_line="$2" local repeat="$4" local left_position="$3" local line_simbol='\u2501' local line left_indent spacer [[ $width_line -ne 0 ]] && spacer="\e[${width_line}C" [[ $left_position -ne 0 ]] && left_indent="\e[${left_position}C" case "$position" in --top) left_corner='\u250F' right_corner='\u2513' ;; --bottom) left_corner='\u2517' right_corner='\u251B' ;; --blank) left_corner='\u2503' right_corner='\u2503' ;; --box-separator) left_corner="\u2523" right_corner="\u252B" ;; esac if [[ "$position" == '--blank' ]]; then while read -r;do line+="${left_indent}${left_corner}${spacer}${right_corner}\n" done < <(seq "$repeat") printf '%b' "$line" else while read -r;do line+="$line_simbol" done < <(seq "$width_line") printf '%b%b%b%b\n' "${left_indent}" "$left_corner" "$line" "$right_corner" fi } draw_frame () { local footer_height frame_color frame_height frame_width local top_position left_position restore_position start_write local terminal_width terminal_width=$(tput cols) local terminal_hight terminal_hight=$(tput lines) until [[ "$#" -eq 0 ]]; do case "$1" in -t) if [[ "$2" =~ ^[0-9]+$ ]];then if [[ "$2" -lt "$(( terminal_hight - 5 ))" ]];then top_position="$2" else top_position="$(( terminal_hight - 5 ))" fi shift else if [[ -z "$2" ]]; then top_position=0 else echo 'Set a positive numeric value for the top position of frame' fi fi ;; -l) if [[ "$2" =~ ^[0-9]+$ ]];then if [[ "$2" -lt "$(( terminal_width - 2 ))" ]];then left_position="$2" else left_position="$(( terminal_width - 2 ))" fi shift else if [[ -z "$2" ]]; then left_position=0 else echo 'Set a positive numeric value for the left position of frame' fi fi ;; -w) if [[ "$2" =~ ^[0-9]+$ ]];then if [[ "$2" -lt "$(( terminal_width - 2 ))" ]];then frame_width="$2" else frame_width="$(( terminal_width - 2 ))" fi shift else echo 'Set a positive numeric value for the frame width' tput cnorm return 1 fi ;; -h) if [[ "$2" =~ ^[0-9]+$ ]];then if [[ "$2" -lt "$(( terminal_hight - 5 ))" ]];then frame_height="$2" else frame_height="$(( terminal_hight - 5 ))" fi shift else echo 'Set a positive numeric value for the frame height' tput cnorm return 1 fi ;; -c) if [[ "$2" =~ \\e\[[0-9]{1,2}m$ ]]; then frame_color="$2" shift else [[ "$2" ]] && { [[ "$2" =~ ^- ]] || shift } fi ;; -f) if [[ "$2" =~ ^[0-9]+$ ]];then footer_height="$2" shift else [[ "$2" ]] && { [[ "$2" =~ ^- ]] || shift } footer_height=1 fi ;; -r|--restore-position) restore_position='1' ;; -s|--start-write) start_write='1' ;; esac shift done top_position=${top_position:-0} left_position=${left_position:-0} [[ "$start_write" ]] && restore_position= [[ "${restore_position:-0}" -eq 1 ]] && tput sc # Сохраняем позицию курсора tput civis clear tput cup "$top_position" 0 if [[ $(( frame_width + left_position )) -gt $(( terminal_width - 2 )) ]];then frame_width=$(( terminal_width - left_position - 2 )) fi if [[ $(( frame_height + top_position )) -gt $(( terminal_hight - 5 )) ]];then frame_height=$(( terminal_hight - top_position - 5 )) fi [[ "$frame_color" ]] && printf '%b' "$frame_color" if [[ "$frame_width" ]] && [[ "$frame_height" ]]; then draw_line --top "$frame_width" "$left_position" draw_line --blank "$frame_width" "$left_position" "$frame_height" [[ -n "$footer_height" ]] && \ draw_line --box-separator "$frame_width" "$left_position" && \ draw_line --blank "$frame_width" "$left_position" "$footer_height" draw_line --bottom "$frame_width" "$left_position" fi [[ "$frame_color" ]] && printf '%b' '\e[0m' [[ "${restore_position:-0}" -eq 1 ]] && { tput rc # Восстановить позицию } [[ "$footer_height" ]] && (( footer_height++ )) [[ "${start_write:-0}" -eq 1 ]] && \ printf '%b' \ "\\e[$(( frame_height + 1 + ${footer_height:-0} ))A\\e[$(( left_position + 1 ))C" tput cnorm } -w 帧宽度; -h 帧高度不包括页脚; -c 框架颜色; -f 页脚高度; 高度和宽度分别是行数和字符数,可以在不钩框架本身的情况下输入 如果你省略 -f,那么只会有一个没有页脚的框 如果你省略 -c,那么边框的颜色将是你终端的标准 draw_frame -w 50 -h 20 -c ${C[Green]} -t 5 -l 5 -f 1 所有尺寸分别在终端的列和行中。 UPD 改进 了一点,现在可以设置框相对于终端左上角的位置: -l 左移 -t 下移 一个好处。添加了两个选项: -r [--restore-position] - 将光标返回到绘图开始之前的位置 -s [--start-write] - 将光标设置到空帧字段的左上角
这是发生的事情:
所有尺寸分别在终端的列和行中。
UPD 改进
了一点,现在可以设置框相对于终端左上角的位置:
一个好处。添加了两个选项: