Shell

如何在不刪除任何尾隨換行符的情況下將標準輸入擷取到變數?

  • March 10, 2021

在 shell 腳本中…

如何在不刪除任何尾隨換行符的情況下將標準輸入擷取到變數?

現在我已經嘗試過:

var=`cat`
var=`tee`
var=$(tee)

在所有情況下$var都不會有輸入流的尾隨換行符。謝謝。

另外:如果輸入中沒有尾隨換行符,則解決方案不得添加一個.

根據接受的答案進行更新:

我在程式碼中使用的最終解決方案如下:

function filter() {
   #do lots of sed operations
   #see https://github.com/gistya/expandr for full code
}

GIT_INPUT=`cat; echo x`
FILTERED_OUTPUT=$(printf '%s' "$GIT_INPUT" | filter)
FILTERED_OUTPUT=${FILTERED_OUTPUT%x}
printf '%s' "$FILTERED_OUTPUT"

如果您想查看完整程式碼,請查看擴展器的 github 頁面,是我為資訊安全目的開發的一個小型開源git 關鍵字擴展過濾器shell 腳本。根據.gitattributes文件(可以是特定於分支的)和git config中設置的規則,git 在將每個文件簽入或簽出儲存庫時通過expandr.sh shell 腳本通過管道傳輸每個文件。(這就是為什麼保留任何尾隨換行符或缺少換行符至關重要的原因。)這使您可以清理敏感資訊,並為測試、暫存和實時分支交換不同的環境特定值集。

在值儲存在變數中之前,尾隨的換行符被剝離。您可能想要執行以下操作:

var=`cat; echo x`

並使用${var%x}而不是$var. 例如:

printf "%s" "${var%x}"

請注意,這解決了尾隨換行符問題,但不是空字節一(如果標準輸入不是文本),因為根據 POSIX 命令替換

如果輸出包含任何空字節,則行為未指定。

但是 shell 實現可能會保留空字節。

您可以使用read內置來完成此操作:

$ IFS='' read -d '' -r foo < <(echo bar)

$ echo "<$foo>"
<bar
>

對於讀取 STDIN 的腳本,它只是:

IFS='' read -d '' -r foo

 

不過,我不確定這將在哪些外殼中起作用。但在 bash 和 zsh 中都可以正常工作。

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