Bash
關於 bash 命令與變數替換的混淆
自 1989 年以來,我一直在命令行上編寫單行 bash 腳本。這些腳本通常具有以下形式:
for name in 1 2 3; do wc $name.txt; done
現在我正在嘗試使用 GIMP 進行一些圖像處理,使用的腳本需要兩個文件名作為參數。這是給我一個有效命令行的東西:
/Applications/GIMP.app/Contents/MacOS/GIMP -b '(script-fu-overlay "png0004.tif" "png0000.tif") (script-fu-overlay "png0004.tif" "png0001.tif") (script-fu-overlay "png0004.tif" "png0002.tif") (script-fu-overlay "png0004.tif" "png0003.tif")'
它是在典型的單線的幫助下生成的:
X=\'$(for name in 0 1 2 3; do echo \(script-fu-overlay \"png0004.tif\" \"png000$name.tif\"\) ; done)\'
但是……這是我的問題:
echo /Applications/GIMP.app/Contents/MacOS/GIMP -b $X
給了我上面的確切命令行,但是當我執行時
/Applications/GIMP.app/Contents/MacOS/GIMP -b $X
我收到有關無法打開帶有引號的文件名的錯誤,但是當我執行時
/Applications/GIMP.app/Contents/MacOS/GIMP -b "$X"
一切正常。我真正的目標是了解我是否有可能在完全不訴諸變數的情況下編寫單行程式碼。就像是:
/Applications/GIMP.app/Contents/MacOS/GIMP -b \'$(for name in 0 1 2 3; do echo \(script-fu-overlay \"png0004.tif\" \"png000$name.tif\"\) ; done)\'
但這顯然以同樣的方式失敗了
/Applications/GIMP.app/Contents/MacOS/GIMP -b $X
失敗。
是的,您可以在命令行上執行此操作,而無需使用 shell 變數。
/Applications/GIMP.app/Contents/MacOS/GIMP -b "$(for name in 0 1 2 3; do echo \(script-fu-overlay \"png0004.tif\" \"png000$name.tif\"\) ; done)"
請注意,我們需要取消轉義的單引號,因為我們不在
eval
這裡做。唯一需要的是命令擴展 $(…) 周圍的雙引號,以防止發生單詞拆分,並將結果作為單個參數傳遞給gimp
.
那這個呢:
$ /Applications/GIMP.app/Contents/MacOS/GIMP -b \ "$(printf '%s\n' '(script-fu-overlay "png0004.tif" "png'{0..0004}'.png")')"