
我有一個驗證表條目的 bash 腳本。最終輸出值是 $out,它被插入到 SQL INSERT 語句中,然後附加到 /tmp/crew.txt。雖然 $out 明顯以逗號分隔,但 /tmp/crew.txt 中產生的 INSERT 語句中的值之間沒有逗號。為什麼會發生這種情況以及如何修復它,以便我在 /tmp/crew.txt 中有逗號分隔的值?
#!/bin/bash
out=290,'02:20:00','02:40:00',20.5,NULL
echo "${out:1}"
290,'02:20:00','02:40:00',20.5,NULL
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ("${out:1}");" >> /tmp/crew.txt
vi /tmp/crew.txt
INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ( 290 '02:20:00' '02:40:00' 20 NULL);
因此 /tmp/crew.txt 中的結果應該是:
INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ( 290,'02:20:00','02:40:00',20,NULL);
答案1
假設:你的IFS
變數包含,
.該腳本不會更改IFS
,因此非預設值必須已在環境中。
這個另一個答案注意到您${out:1}
在如下所示的行中未加引號:
echo "foo"${out:1}"bar"
不含引號的變數進行分詞和檔名生成。分詞是透過IFS
.未加引號的內容${out:1}
被拆分為多個單詞,echo
獲取多個參數並列印它們,並用單個空格分隔(因為這就是作用echo
,無論IFS
)。
如果你用過printf
按照建議,會更容易判斷變數是否被引用:
printf 'INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (%s);\n' "${out:1}"
如果您沒有雙引號變量,printf
則會從中取得多個參數${out:1}
,並且會產生多行。那麼很明顯會發生一些分裂。使用echo
它連接它的參數在某種程度上混淆了這個事實。
單獨的問題:
所需的輸出表示您不想要
"${out:1}"
但" $out"
有一個前導空格。要在變數中包含單引號,您應該確保 shell 不會刪除它們。逃離他們(歸功於已經提到的答案) 或用雙引號引起來:
out="290,'02:20:00','02:40:00',20.5,NULL"
答案2
為什麼會出現這種情況以及如何解決
從腳本中刪除回顯的輸出和空白行會得到以下清理後的腳本:
#!/bin/bash
out=290,'02:20:00','02:40:00',20.5,NULL
echo "${out:1}"
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ("${out:1}");" >> /tmp/crew.txt
不過運行該腳本ShellCheck – shell腳本分析工具產生以下錯誤:
$ shellcheck myscript
Line 4:
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ("${out:1}");" >> /tmp/crew.txt
>> ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
$
按照建議刪除引號可以修復該錯誤,所以現在我們有:
#!/bin/bash
out=290,'02:20:00','02:40:00',20.5,NULL
echo "${out:1}"
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (${out:1});" >> /tmp/crew.txt
然而,運行它仍然沒有給出正確的答案,因為echo "${out:1}"
表明單引號'
沒有儲存在 中out
,並且需要對它們進行轉義:
$ test.sh
90,02:20:00,02:40:00,20.5,NULL
$
解決這個問題可以得到:
#!/bin/bash
out=290,\'02:20:00\',\'02:40:00\',20.5,NULL
echo "${out:1}"
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (${out:1});" >> test.txt
注意我已將輸出檔名更改為test.txt
測試:
$ test.sh
90,'02:20:00','02:40:00',20.5,NULL
$ cat test.txt
INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (90,'02:20:00','02:40:00',20.5,NULL);
$
所以腳本的最終固定版本是:
#!/bin/bash
out=290,\'02:20:00\',\'02:40:00\',20.5,NULL
echo "${out:1}"
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (${out:1});" >> >> /tmp/crew.txt
關於調試損壞的腳本的課程到此結束。
答案3
對我有用的解決方案是回顯以下 INSERT 語句:
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (${out:1});" >> /tmp/crew.txt
沒有必要逃避。但不確定原因。