我的 bash 腳本中的 qoutes 有問題
如何在這個從數據庫中搜尋內容的腳本中做到這一點。他搜尋並在終端中更改了它的名稱。我對這裡的引號有疑問。也許有人知道如何解決它?
spr-ustawien() { echo -e "\e[31;43mSprawdzanie Ustawień\e[0m \e[101mIP $1\e[0m" intertube=0 while [ $intertube -ne 1 ]; do ping $1 -c 5 if [ $? -eq 0 ]; then sshpass -p (pass) ssh -t (user)@$1 " sudo sqlite3 config.sqlite "SELECT * FROM settings" |grep "SALE_POINT" | awk '{sub(/SALE_POINT/,"\033[1mPunkt Sprzedaży:\033[0m")}1' && exit " echo -e "\e[1;5;32mSprawdzony\e[0m" intertube=1; else echo -e "\e[1;5;31m!!! JEST OFFLINE !!!\e[0m" break fi done }
在我看來,基本問題是引號不會像您在
ssh
命令中使用它們的方式那樣嵌套。也就是說,在這個命令中:sshpass -p (pass) ssh -t (user)@$1 " sudo sqlite3 config.sqlite "SELECT * FROM settings" |grep "SALE_POINT" | awk '{sub(/SALE_POINT/,"\033[1mPunkt Sprzedaży:\033[0m")}1' && exit "
"
in"SELECT * FROM...
實際上是一個關閉引號(與前一行的打開引號匹配),因此它實際上是完全未引用的,而不是在SELECT * FROM settings
兩層引號內(因此,*
將擴展為本地目錄中的文件列表,造成誰知道什麼混亂)。正如 djdomi 在評論中所說,您可以
ssh
通過將ssh
命令替換為echo
. 當我執行這個:echo " sudo sqlite3 config.sqlite "SELECT * FROM settings" |grep "SALE_POINT" | awk '{sub(/SALE_POINT/,"\033[1mPunkt Sprzedaży:\033[0m")}1' && exit "
它列印:
sudo sqlite3 config.sqlite SELECT file1.txt file2.jpg FROM settings |grep SALE_POINT | awk '{sub(/SALE_POINT/,033[1mPunkt Sprzedaży:033[0m)}1' && exit
最直接的解決方案是轉義內部雙引號,因此本地 shell 會將它們傳遞給遠端系統上的 shell:
sshpass -p (pass) ssh -t (user)@$1 " sudo sqlite3 config.sqlite \"SELECT * FROM settings\" |grep \"SALE_POINT\" | awk '{sub(/SALE_POINT/,\"\033[1mPunkt Sprzedaży:\033[0m\")}1' && exit "
請注意,您必須轉義所有這些,即使是單引號
awk
命令中的那些,因為這些單引號對本地 shell 沒有任何意義。…但我建議稍微簡化一下。我看不出有任何理由,
grep
需要awk
在遠端系統而不是本地系統上執行(並且該exit
命令沒有做任何有用的事情,因為它無論如何都會退出)。因此,您可以將grep
and命令移到awk
命令之外ssh
:sshpass -p (pass) ssh -t (user)@$1 "sudo sqlite3 config.sqlite \"SELECT * FROM settings\"" | grep "SALE_POINT" | awk '{sub(/SALE_POINT/,"\033[1mPunkt Sprzedaży:\033[0m")}1'
而且我總是討厭看到
grep
used beforeawk
,當awk
完全能夠自己做所有事情時:sshpass -p (pass) ssh -t (user)@$1 "sudo sqlite3 config.sqlite \"SELECT * FROM settings\"" | awk '/SALE_POINT/ {sub(/SALE_POINT/,"\033[1mPunkt Sprzedaży:\033[0m"); print}'
我還建議雙引號所有變數引用(例如,
ping "$1" -c 5
而不是 justping $1 -c 5
),並替換它:ping $1 -c 5 if [ $? -eq 0 ]; then
只需:
if ping "$1" -c 5; then
最後我會推薦
printf
而不是echo -e
- 它更可預測。printf
使用起來有點複雜——第一個參數是一個格式字元串,告訴它如何列印任何剩餘的參數,並且它不會在末尾自動添加換行符(所以用 顯式添加一個\n
)——但它更少可能會因為 shell 版本的一些變化而中斷echo
(就像我不久前發生的那樣……)。所以使案例如printf "\e[31;43m%s\e[0m \e[101m%s1\e[0m\n" "Sprawdzanie Ustawień" "IP $1"
哦,我總是建議通過shellcheck.net執行你的腳本——它會指出許多常見的錯誤和不良做法。