Bash

在命令替換中轉義雙引號

  • September 17, 2020

我正在嘗試編寫一個簡單的 bash 解析器。我正在按照這個wiki中的步驟進行操作。我做出的一個假設是,如果我正確轉義字元,我可以對整個輸入字元串進行傳遞並刪除所有單引號和雙引號。在 bash 中執行時,它們的兩個字元串應該產生相同的輸出。

我的解析器的這一部分接受任何給定的字元串並從中刪除單引號和雙引號(除了被轉義並解釋為文字的引號)。在 bash 中執行時,兩個字元串仍應產生相同的結果。

我的解析器將原始文件轉換為 My Parse,如下所示。但是,原始作品,但 My Parse 沒有。

# Original
$ node -p "console.log($(echo \"hello world\"))"
hello world


# My Parse: Escape everything within double quotes except command substitution
                                 v                      v
$ node -p \c\o\n\s\o\l\e\.\l\o\g\($(echo \"hello world\")\)
[eval]:1
console.log("hello
           ^^^^^^

SyntaxError: Invalid or unexpected token

我對為什麼我的解析錯誤有幾個想法。

  1. 我不了解雙引號內的命令替換如何工作的一些基本方面。我的理解是首先發生命令替換,然後處理引號。
  2. 我不了解實際輸出命令替換的一些基本方面。我的理解是$(echo \"hello world\")應該產生一個字元串"hello world"而不是命令"helloworld"
  3. 該命令有一些特殊性echo(可能是因為它是可變參數)。實際上,我很幸運這在原始場景中有效,但實際上,更改命令替換中的命令可能會破壞它……
  4. 我的節點/javascript 問題有問題。這是非常簡單的js,所以我不認為是這樣……

最後一件有趣的事情:當我將命令替換用雙引號括起來時它會起作用。也許以不同的方式提出整個問題,如果沒有雙引號(不包括轉義的),我怎麼能寫出與下面相同的輸入。

# Escape everything but keep command substitution in double quotes
                                 v                       v
$ node -p \c\o\n\s\o\l\e\.\l\o\g\("$(echo \"hello world\")"\)
hello world

注意:這個問題在某種程度上是這個關於轉義雙引號的問題的後續問題

這就是分的作用。在我們開始之前,請仔細閱讀Shell 擴展,注意它們的執行順序。

看著node -p "console.log($(echo \"hello world\"))"

  • 大括號擴張?不
  • 代字擴展?不
  • 參數擴展?這裡沒有
  • 命令替換?是的,留給你
 node -p "console.log("hello world")"
  • 算術展開?不
  • 流程替代?不
  • 分詞?to 的論點-p用引號引起來,所以沒有。
  • 文件名擴展?不
  • 報價刪除完成

bash 生成node傳遞它 2 個參數,-p並且console.log("hello world")


現在看看node -p console.log($(echo \"hello world\"))

  • 在命令替換之後,我們有node -p console.log("hello world")
  • 當我們進行分詞時,參數 to-p沒有引號來保護它。對於目前命令,bash 有 4 個標記:
 node -p console.log("hello world")
 ^^^^ ^^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^

bash 生成node傳遞3 個參數:-pconsole.log("helloworld")顯然console.log("hello是一個 javascript 語法錯誤,你會看到會發生什麼。


更多關於忘記在 bash/POSIX shell 中引用變數的安全隱患的詳細資訊

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