Bash函式/腳本參數完全複製到變數中
如何將 Bash 函式/腳本參數完全複製到變數中,因為
'
(可能還有其他字元)不能保留在變數中?例如
m() { v="$@" echo "$v" } $ m let it be 'foo' bar let it be foo bar
感謝真誠的幫助,謝謝。
這裡要注意的是,當你執行例如
m let it be 'foo bar'
該程序
m
沒有得到整個命令行,但shell首先解析命令行,處理引號、變數擴展和類似的東西。該命令的最終結果更像是一個單獨的字元串數組,在本例中為 [let
,it
,be
,foo bar
]。同樣,在
f="James Matthew" l="Bond" m "$l, $f $l"
m
只會看到 [Bond, James Matthew Bond
],並且不知道所涉及的變數和引號。這意味著正常程序無法訪問原始輸入行。
在Any shell 中,在沒有轉義或引用的情況下關閉擴展的情況下,使用 pre-exec 處理程序的 zsh 有解決方法?和zsh: alias or shell function 只回顯它的命令行,包括 shell control characters,但我想我沒見過 Bash 的。
最接近你的是
DEBUG
陷阱,它看到在擴展、報價處理和重定向之前要執行的命令。但它並不完整,因為它一次只能看到一個簡單的命令。評論會在看到它們之前被刪除,並且未引用的;
,&
,|
,&&
,||
,(
或)
(至少)仍將被解析。無論如何,我們可以嘗試:
#!/bin/bash shopt -s extdebug handle_@() { local re='[[:space:]]*@ ([^[:space:]]+)[[:space:]]+(.*)' if [[ $BASH_COMMAND =~ $re ]]; then "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" return 1 fi } m() { printf "<%s>\n" "$1" } trap handle_@ DEBUG @ m 'foo bar' doo "$var" > /dev/null @ m what about this?; date @ m or some (parentheses)?
該腳本使用
DEBUG
陷阱檢測以 開頭的命令@
,將下一個以空格分隔的“單詞”作為要執行的命令,並將其餘的作為單個參數傳遞給它。從陷阱處理程序返回1
告訴 shell 實際上不執行命令(使用extdebug
set。)輸出是這樣的,顯示
date
分號之後的執行,並且括號破壞了語法:<'foo bar' doo "$var" > /dev/null> <what about this?> Sun Sep 18 18:39:38 EEST 2022 debugprint.sh: line 20: syntax error near unexpected token `(' debugprint.sh: line 20: `@ m or some (parentheses)?'
這是一組相當隨意的限制,我不能保證腳本也沒有其他問題。
一般來說,如果您計劃將此用於某種生產用途,我建議重新考慮程序的結構並通過文件或例如 here-doc 獲取字元串,具體取決於您在做什麼。
一個 here-doc 使得輸入原始字元串變得相對容易,儘管它通過命令的
stdin
:m() { m=$(cat) printf "<%s>\n" "$m" } m <<'EOF' Say "$hello" to my 'little friend' EOF
那列印
<Say "$hello" to my 'little friend'>
使用帶引號的 here-doc 分隔符字元串 (in
<<'EOF'
),您可以在其中放置任意文本和字元,而無需擔心引號。(當然,除了分隔符字元串本身,但您可以使用隨機生成的字元串來代替EOF
.)