這個問題在這里已經有了答案: 我如何在沒有換行符的情況下“回顯”內容? (4 個回答) 如何從 Bash 函式中回傳字串值 20 個回答 14 小時前關閉。
此帖已于14 小時前編輯并提交審核。
我一直在使用 bash 中的多行字串(無需調出 bash 陣列,這是 POSIX 的東西)。完整的作業演示發布在在線 BASH 仿真器中。
我遇到的問題是,每次我呼叫一個函式并回傳一個字串時,處理多行字串的正確方法會無意中導致在字串末尾附加一個額外的 chr(10)。
建議的重復項不適用:
- 如何從 Bash 函式回傳字串值- 它不能正確處理多行字串變數末尾的空行。
- 我如何在沒有換行符的情況下“回顯”內容?- 它不談論多行非陣列字串變數。
這個多行 bash 字串的作業示例正確地在末尾有一個空行,并且是:
# bash variable declared as multi-line string
ini_buffer="1.1.1.1"
"
將原始多行字串轉換為長度為 8 的十六進制轉儲:
00000000 31 2e 31 2e 31 2e 31 0a 00 |1.1.1.1..|
00000009
Bash 腳本開始于:
# there is exactly one chr(10) at the end of ini_buffer
ini_buffer="1.2.3.4
"
echo "initial ini_buffer \"\"\"$ini_buffer\"\"\""
echo "initial ini_buffer len: ${#ini_buffer}"
echo
IFS= read -rd '' result < <(echo "$ini_buffer")
# got a SECOND chr(10) prepended to the final output
echo "result len: ${#result}"
echo "\"\"\"$result\"\"\""
echo
結果是:
initial ini_buffer """1.2.3.4
"""
initial ini_buffer len: 8
result len: 9
"""1.2.3.4
"""
注意到它長出了一個角色?!
00000000 31 2e 31 2e 31 2e 31 0a 0a 00 |1.1.1.1..|
00000009
添加了第一個功能:
first_function()
{
local first_buffer result1_buffer
# takes a string with a single chr(10)
first_buffer="$1"
# calls a function, which does nothing.
IFS= read -rd '' result1_buffer < <(second_function "$first_buffer")
# yet it got prepended by another chr(10) for a total of two chr(10)
echoerr "result1_buffer len: ${#result1_buffer}"
echoerr "\"\"\"$result1_buffer\"\"\""
# Suuposedly only one way to return a multi-line string neatly,
# and that is via STDOUT (fd=1)
# echo "first_buffer len: ${#first_buffer}"
echo "$result1_buffer"
}
# there is exactly one chr(10) at the end of ini_buffer
ini_buffer="1.2.3.4
"
echo "initial ini_buffer \"\"\"$ini_buffer\"\"\""
echo "initial ini_buffer len: ${#ini_buffer}"
echo
# THIS LINE CHANGED from `echo` to `first_function`
IFS= read -rd '' result < <(first_function "$ini_buffer")
# got a SECOND chr(10) prepended to the final output
# for a total of 3 prepended chr(10)s
echo "result len: ${#result}"
echo "\"\"\"$result\"\"\""
echo
第一個函式的結果是:
initial ini_buffer """1.2.3.4
"""
initial ini_buffer len: 8
result1_buffer len: 9
"""1.2.3.4
"""
result len: 10
"""1.2.3.4
"""
Every time that a function returning from a nested-called, another chr(10) gets tacked on to it upon return.
This also got increase when a second function was introduced of which I shall not include here for brevity.
This is getting maddening here to me. Has to do with the last-line being blank (or jus a chr(10) character). Not many online authoritative content on proper handling of multi-line string.
What did I do wrong?
Process substitution (<( ... )) gets used here instead of the usual command substitution ($( ... )) which had shown difficulty in working with multi-line string. As a result, I must output any debug stattement to the STDERR using:
echoerr() { printf "%s\n" "$*" >&2; }
I would like to do the proper thing of bash progrmaming with regard to multi-line handling, notably with blank line(s) at the end of its string.
A complete test is reiterated here (working demo link is in cited in the first paragraph):
echoerr() { printf "%s\n" "$*" >&2; }
dump_string_char()
{
local string len_str idx this_char this_int
string="$1"
echoerr "string: \"\"\"$string\"\"\""
len_str="${#string}"
idx=0
while [ $idx -lt ${len_str} ]; do
this_char="${string:$idx:1}"
this_int="$(LC_CTYPE=C printf "%d" "'$this_char")"
echoerr "idx: $idx"
if [ $this_int -lt 32 ]; then
echoerr "$idx: ${this_int}"
else
echoerr "$idx: \"${this_char}\""
fi
((idx ))
done
}
second_function()
{
local second_ini_buffer result2_buffer
second_ini_buffer="$1"
# Some magical awk/sed that did not match any pattern
# So let us use 'echo' to re-save the same string
IFS= read -rd '' result2_buffer < <(echo "$second_ini_buffer")
echoerr "result2_buffer len: ${#result2_buffer}"
echoerr "\"\"\"$result2_buffer\"\"\""
# so pass back the full ini_buffer as-is.
# hopefully with ONE chr(1) at end-of-line.
# but it doesn't.
echo "$result2_buffer"
}
first_function()
{
local first_buffer result1_buffer
# takes a string with a single chr(10)
first_buffer="$1"
# calls a function, which does nothing.
IFS= read -rd '' result1_buffer < <(second_function "$first_buffer")
# IFS= read -rd '' result1_buffer < <(echo "$first_buffer")
# yet it got prepended by another chr(10) for a total of two chr(10)
echoerr "result1_buffer len: ${#result1_buffer}"
echoerr "\"\"\"$result1_buffer\"\"\""
# Suuposedly only one way to return a multi-line string neatly,
# and that is via STDOUT (fd=1)
# echo "first_buffer len: ${#first_buffer}"
echo "$result1_buffer"
}
# there is exactly one chr(10) at the end of ini_buffer
ini_buffer="1.2.3.4
"
echoerr "initial ini_buffer \"\"\"$ini_buffer\"\"\""
echoerr "initial ini_buffer len: ${#ini_buffer}"
echoerr
dump_string_char "$ini_buffer"
IFS= read -rd '' result < <(first_function "$ini_buffer")
# got a SECOND chr(10) prepended to the final output
# for a total of 3 prepended chr(10)s
echoerr "result len: ${#result}"
echoerr "\"\"\"$result\"\"\""
echoerr
uj5u.com熱心網友回復:
你的問題是echo總是在你的字串末尾添加一個換行符 - 如果它已經包含一個,它將有兩個。由于您總是“回傳” using echo "$result",因此每次它都會添加一個新的。
您應該嘗試使用printf "%s" "$result":
ini_buffer="1.2.3.4
"
echo "initial ini_buffer len: ${#ini_buffer}"
IFS= read -rd '' result < <(printf "%s" "$ini_buffer")
echo "result len: ${#result}"
結果:
initial ini_buffer len: 8
result len: 8
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/439444.html
標籤:bash
上一篇:如何按名稱選擇一行以及bash或python中的前一行?
下一篇:rsync不適用于包含空格的變數
