Linux

為什麼我的 find (+ sed) 命令在終端中有效,但在 makefile 中無效?

  • April 12, 2019

我有以下命令:

find stdlib/main -type f -exec sh -c "echo {} | sed -e 's/stdlib\/main\///g' -e 's/\.q//g' -e 's/\//\./g' -e 's~^~/resource:\"{},~g' -e 's/$/\"/g'" \;

目標是找到stdlib/main(和子目錄)中的所有文件並將它們格式化為:{filename},{filename-with-stdlibmain-removed-and-extension-removed-and-slashes-changed-to-dots}

當我自己執行該命令時,它可以完美執行。但我試圖在makefile中使用它:

STDLIB_RESOURCES=$(shell find stdlib/main -type f -exec sh -c "echo {} | sed -e 's/stdlib\/main\///g' -e 's/\.neo//g' -e 's/\//\./g' -e 's~^~/resource:\"{},~g' -e 's/$/\"/g'" \;)

當我執行 makefile 時,每個找到的文件都會出現以下錯誤之一:

sed: -e expression #5, char 5: unterminated `s' command

我在這裡想念什麼?

您缺少的主要內容是$要製作的特殊字元,並且在 Make 和 shell 中引用是不同的。

所以例如

's/$/\"/g'

`` 對將它們內部的所有內容保護到外殼中(順便使\不必要的),但不做,所以讓它看起來像

's/\"/g' 

假設你沒有一個名為的變數/(你可以在 make 中,但通常不在 shell 中)。

首先要做的是替換$$$.

{}在您執行的內聯腳本中使用是find一個程式碼注入漏洞。不要那樣做。(腳本)的第一個參數sh -c應該是單引號,並且該腳本的參數應該在其命令行上傳遞。

相反,將find命令編寫為如下所示(使用bash而不是sh能夠${parameter//pattern/word}在一個地方使用):

find stdlib/main -type f -exec bash -c '
   for pathname do
       string=${pathname#stdlib/main/} # delete initial path
       string=${string%.*}             # delete suffix after last dot
       string=${string////.}           # change slashes to dots

       # output:
       printf "resource:\"%s,%s\"\n" "$pathname" "$string"
   done' bash {} +

這不是使用sed,而是使用參數替換來修改由 找到的路徑名find。將針對找到的文件批次執行內聯bash腳本,並將遍歷每個批次中的路徑名。printf將以與您的命令相同的方式輸出轉換的數據(sed如果我設法正確破譯它,那不僅僅是您所描述的)。

以後如何處理包含雙引號和逗號的文件名是另一個問題(之後的輸出字元串resource:可能難以解析)。

find命令放入單獨的腳本並從 GNU makein呼叫它是最簡單的$(shell ...),否則你最終會得到類似的東西

STDLIB_RESOURCES := $(shell     \
find stdlib/main -type f -exec bash -c '    \
   for p do                                \
       s=$${p\#stdlib/main/};              \
       s=$${s%.*};                         \
       s=$${s////.};                       \
       printf "resource:\"%s,%s\"\n" "$$p" "$$s"; \
   done' bash {} + )

在您的 Makefile 中(由於 GNUmake處理變數等的方式)還要注意:=. 您需要這個命令在分配給變數時立即執行,而不是每次訪問變數時。

有關的:

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