単純なbashパーサーを作成しようとしています。私はこのステップに従いますウィキペディア。私が仮定したことの1つは、文字を正しくエスケープすることで、入力文字列全体を繰り返すことで一重引用符と二重引用符の両方を削除できることでした。 Bashで実行すると、これら2つの文字列は同じ出力を生成する必要があります。
私のパーサのこの部分は与えられた文字列を取得し、一重引用符と二重引用符を削除します(エスケープされてリテラルとして解釈される引用符を除く)。 Bashで実行すると、両方の文字列はまだ同じ結果を生成する必要があります。
マイパーサーは、次のように生のコンテンツをマイパーサーに変換します。しかし、オリジナルは動作しますが、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
解析エラーの原因についていくつかのアイデアがあります。
二重引用符内のコマンド置換がどのように機能するかについていくつかの基本的な側面を理解していません。私の理解は、コマンド置換が最初に発生し、次に引用符が処理されることです。
コマンド置換が実際にどのように出力されるかについてのいくつかの基本的な側面を理解していません。私の理解は、コマンドではなく
$(echo \"hello world\")
文字列を生成する必要があるということです。"hello world"
"hello
world"
このコマンドにはいくつかの特徴があります
echo
(おそらく変更可能だからです)。実際に運が良かったので、元のシナリオでは動作しましたが、実際にはコマンドの置き換えからコマンドを変更すると問題が発生する可能性があります。ノード/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
注:この質問は少し後続の質問です。二重引用符エスケープに関するこの質問
ベストアンサー1
これは噴射行動中。始める前に注意深くお読みください。シェル拡張実行される順序に注意してください。
見ているnode -p "console.log($(echo \"hello world\"))"
拡張をサポートしていますか?いいえ
チルダ拡張?いいえ
パラメータ拡張?ここではない
コマンドの置き換え?うん、任せてください。
node -p "console.log("hello world")"
算術拡張?いいえ
プロセスの交換?いいえ
噴射?パラメータは
-p
引用符で囲まれているため、そうではありません。ファイル名拡張子?いいえ
見積もりの削除完了
node
bashは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
これによって生成されます。サム引数:-p
と - は明らかにJavaScript構文エラーですconsole.log("hello
。何が起こるのか見てみましょう。world")
console.log("hello
詳細については、次を参照してください。bash / POSIXシェルで変数を引用することを忘れてしまうセキュリティリスク