Shell
如何在不刪除任何尾隨換行符的情況下將標準輸入擷取到變數?
在 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 中都可以正常工作。