Bash

互動式 bash 腳本:使用字元串為所有行添加前綴

  • December 4, 2019

我想在 bash 中創建一個互動式 CLI。類似於 bash 為每一行添加前綴的方式user@host:~$,我想在每一行添加前綴foobar>。此功能可以在 Metasploit 或 mysqli 等 CLI 應用程序中看到,但它們使用單獨的程式語言,而我想簡單地使用 bash 腳本。此外,我需要向上/向下箭頭鍵來使用該history功能(或類似功能),允許使用者輕鬆調出最後一個輸入或之前的第 n 個輸入。

在嘗試創建解決方案時,我遇到了這個答案,它允許 bash 解釋箭頭鍵並使用history. 這很好用,但是我很難將它與行前綴結合起來。我在這裡找到了一個使用 coproc 預處理標準輸出的解決方案並實現了一個版本,但是,這種方法既不適用於您正在輸入的輸入行,也不適用於使用帶有history. 我到目前為止的 bash 腳本如下:

exec 4>&1
coproc out (sed 's/^/foobar> /' >&4)
exec 1>&${out[1]}

printf "foobar> " >&4
while read -e x; do
  history -s "$x"
  echo $x
done

這是詳細說明這兩個問題的輸出。正如您在下面看到的,我可以通過printf "foobar> " >&4在 while 循環之前在上面的腳本中使用來為 cli 的第一行添加前綴。下面我boop在第一行輸入,echo 的輸出被重定向到我的 coproc。但是在此之後,使用向上箭頭將輸入boop帶回將列印boop沒有我的前綴(如最後一行所示)。

$ ./test.sh
foobar> boop
foobar> boop
boop

我確實意識到,因為我在循環中沒有 printf,所以我正在輸入的行在第一次迭代後不會加前綴。稍後我可以通過重做循環來解決這個問題(儘管我擔心將前綴行發送到前綴 coproc,因此需要雙前綴)。我主要需要解決的是向上箭頭輸出沒有加前綴。我假設這些資訊是通過 發送的stdout,但顯然不是。我也嘗試過stderr以相同的方式重定向,但這會阻止終端在我輸入時回顯我輸入的內容。

我需要一個解決方案來為 bash 腳本中的每一行添加前綴,無論它是基於我上面提供的腳本建構還是使用不同的方法。我還希望它盡可能優雅,因為我將使用這種技術建構一個 CLI 工具,並且希望盡可能少的額外成本。我認為重定向會為我做到這一點,但顯然它比我最初想像的要復雜。

我並沒有真正關注這coproc件事。在你的情況下read -p似乎恰到好處。您可能希望使用單獨的(非預設)歷史文件。

警告:腳本創建/用於$HOME/.custom_history保存其歷史記錄。測試解決方案後,手動刪除文件。

#!/bin/bash

# History management
hfile="$HOME/.custom_history"
HISTCONTROL=ignoreboth
history -r "$hfile"
trap 'history -a "$hfile"' exit

# Main loop
while read -ep 'foobar> ' x; do
  history -s -- "$x"
  printf '%s\n' "$x"
done

從這個問題借來的基本思想。

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