我正在編寫一個客戶端,用於透過 ssh 在 zimbra 伺服器上執行各種任務,但我遇到了一些障礙。這是代碼:
#!/bin/bash
set -e
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
export HISTCONTROL=ignoreboth
# History management
if [ -f $HOME/.zmcli_history ]; then
history -r $HOME/.zmcli_history
else
touch $HOME/.zmcli_history
history -r $HOME/.zmcli_history
fi
trap "history -a $HOME/.zmcli_history && echo -e '\nExiting now.\n'" exit
# Styling
yellow='[33m'
bold='[1m'
off='[0m'
echo
# Client
while :; do
read -ep "$bold${yellow}zimbra_cli[${off}server_domain$bold${yellow}]> $off" comm
history -s "$comm"
done
注意:如果執行此腳本,它將在您的主目錄中建立歷史檔案 (.zmcli_history)。
一切都按預期進行,歷史記錄都在那裡,但當我繼續滾動歷史記錄時,以前的一些(通常很長)命令的部分通常仍然存在。這部分命令將充當會話其餘部分的提示的一部分,除非我按下 CTRL+L 來清除螢幕並將其重置為正常。我讀過許多文章,這些文章幫助了在 bash 終端機中遇到此問題的人。他們的問題是 PS1 格式不正確,而且 bash 對提示字串的長度感到困惑。這裡可能是類似的東西,但是這些解決方案不起作用,因為 read 命令不能使用那些轉義字符,例如 echo 可以(\e)。
我設法找到一種使用文字轉義(vim 插入模式下的 CTRL+V ESCAPE)來轉義顏色序列的方法。所以顏色有效,但我被這個歷史問題困住了。
我嘗試過的事情:
- 命令替換 :: 以 echo -e 可以列印顏色代碼的方式寫入和轉義顏色代碼,然後在讀取命令 $(echo -e '\e[33m') 中回顯它。仍然看到顏色,但對解決歷史問題沒有幫助
- 在顏色代碼周圍添加轉義的 [ 和 ]
- 將帶有顏色代碼的整個提示放在讀取命令之前的單獨的 echo 命令中。缺點是,直到讀取命令之後(在另一個回顯中)我才能關閉格式,這意味著整個提示和命令將是粗體和彩色的。另外,如果我現在按 CTRL+L,連提示都會被清除,只剩下遊標
最後,由於我無法刪除歷史記錄,所以我嘗試刪除顏色。但這樣就不可能快速區分命令和輸出。
您可以透過啟動腳本並輸入 10-15 個長(亂碼)命令來重現問題。之後,嘗試上下滾動歷史記錄,您就會明白我在說什麼。
有人知道如何讓這項工作有效嗎?
答案1
你的劇本,就這樣,不允許我複製這個問題。只有在啟用顏色和這樣的閱讀線之後才開始變得混亂。作為記錄,我啟用了這些功能
# Styling
yellow=$'\e[33m'
bold=$'\e[1m'
off=$'\e[0m'
這是真的\[
,但\]
沒有幫助他們會在以下情況下這樣做PS1
。
但後來我發現這個答案。上面寫著
我打開
info readline
發現:[...]
應用程式可能會指示提示包含在顯示時不佔用物理螢幕空間的字符,方法是將這些字符的序列與特殊標記RL_PROMPT_START_IGNORE
和RL_PROMPT_END_IGNORE
(在 中聲明) 括起來readline.h
。於終端的轉義序列。正如我在其中搜索
RL_PROMPT_START_IGNORE
和RL_PROMPT_END_IGNORE
定義的文本所說readline.h
,然後找到:/* Definitions available for use by readline clients. */ #define RL_PROMPT_START_IGNORE '\001' #define RL_PROMPT_END_IGNORE '\002'
這導致我得出以下結論:
# Styling
yellow=$'\1\e[33m\2'
bold=$'\1\e[1m\2'
off=$'\1\e[0m\2'
它工作完美。