Bash

我的 bash 腳本中的 qoutes 有問題

  • August 21, 2021

如何在這個從數據庫中搜尋內容的腳本中做到這一點。他搜尋並在終端中更改了它的名稱。我對這裡的引號有疑問。也許有人知道如何解決它?

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命令沒有做任何有用的事情,因為它無論如何都會退出)。因此,您可以將grepand命令移到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'

而且我總是討厭看到grepused before awk,當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而不是 just ping $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執行你的腳本——它會指出許多常見的錯誤和不良做法。

引用自:https://serverfault.com/questions/1075251