[英]How to separate multiple commands passed to eval in bash
我正在嘗試使用eval
評估多行 shell 命令,但是當我嘗試使用由換行符分隔的 eval 解析變量時\\n
變量未解析。
x='echo a'
y='echo b'
z="$x\n$y"
eval $x
eval $y
eval $z
哪些輸出:
a
b
anecho b
最后一個命令給出了anecho b
,顯然\\n
在那里被視為n
。 那么有沒有辦法評估多行命令(比如,用\\n
分隔)?
\\n
不是換行符; 它是一個轉義序列,在某些情況下會被轉換為換行符,但您還沒有在其中一種情況下使用它。 變量$z
不包含換行符,只是反斜杠后跟“n”。 結果,這是實際執行的內容:
$ echo a\necho b
anecho b
您可以使用分號代替(不需要翻譯),或者在將被翻譯為換行符的上下文中使用\\n
:
$ newline=$'\n'
$ x='echo a'
$ y='echo b'
$ z="$x$newline$y"
$ eval "$z"
a
b
注意"$z"
周圍的雙引號——它們在這里實際上很重要。 沒有它們,bash 將對$z
的值進行分詞,將所有空格(空格、制表符、換行符)轉換為分詞符。 如果發生這種情況, eval
將收到單詞“echo”“a”“echo”b”,有效地將換行符轉換為空格:
$ eval $z
a echo b
這是雙引號變量引用很重要的一長串案例中的另一個。
您正在將換行符傳遞給 eval。 所以就像你在控制台上輸入:
el@voyager$ echo a\necho b
anecho b
所以第一個echo
被正確理解,它認為你想要其余的引號。 反斜杠似乎被忽略了。 也許你的意思是這樣的:
el@voyager$ echo -e 'a\n'; echo b
a
b
選項1:
使用分號傳遞給 eval 的分隔語句如下:
x='echo a'
y='echo b'
z="$x;$y"
eval $x
eval $y
eval $z
印刷:
a
b
a
b
選項 2:
將換行符放在 echo 將解釋的位置,如下所示:
x='echo -e "a\n"'
y='echo b'
z="$x;$y"
eval $x
eval $y
eval $z
印刷:
a
b
a
b
現在換行符由回聲保留和解釋,而不是由評估。
不一定是最佳方式,因為如果x
和y
變量包含由 printf 處理的序列,如%s
和類似的,它將失敗,但無論如何,這是一種在保持\\n
作為分隔符的同時執行此操作的方法:
x='echo a'
y='echo b'
z="$x\n$y"
eval $x
eval $y
export IFS=" "
eval $(printf "$z")
印刷:
a
b
a
b
一種稍微不同的方法:
read -r -d '' script <<'EOF'
echo a
echo b
EOF
eval "$script"
產出
a
b
read -r -d '' script
-r
- 不允許反斜杠轉義任何字符-d ''
- 繼續直到讀取 DELIM 的第一個字符,而不是換行符(使其讀取到 EOF)script
- 保存結果的變量名<<'EOF'
- 使用沒有變量擴展的heredoc(圍繞EOF
的單引號停止變量擴展)這也可以使用$(cat <<'EOF'...EOF)
,但這種方式不會不必要地使用 cat 並且不使用子shell。
無用貓的示例:
script=$(cat <<'EOF'
echo a
echo b
EOF
)
eval "$script"
在我的 FreeBSD 機器上,我試圖在 Bourne 腳本中做一些事情,這起初看起來相當微不足道 - 但有一段時間讓我的頭腦蒙上了一層陰影。 由於這個頁面是我提到的試圖解決我的問題的頁面,我將解釋我需要做什么以及我是如何完成的:
a=A
b=B
eval ${a}_${b}="something"
到目前為止沒有問題。 我得到一個存儲“東西”的新變量 A_B
但是,如果我將作業分成 2 行,如下所示:
eval ${a}_${b}="some
thing"
shell 對我咆哮說它找不到名為“thing”的命令。 重要的是要了解 eval 嘗試將 RHS 評估為命令。 要讓 eval 將 RHS 評估為字符串,您必須雙雙引號 RHS :
eval ${a}_${b}="\"some
thing\""
希望這可以幫助某人。 馬尼什耆那教
您是否正在考慮使用更強大的 zsh 而不是 bash? 如果是這樣,您可能希望利用過程替換和 heredoc。 以下代碼的工作方式與標題類似。
source <(cat << EOF
command1
command2
EOF
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.