如何在这个从数据库中搜索某些内容的脚本中做到这一点。他搜索了它并在终端中更改了它的名称。我对这里的引号有问题。也许有人知道如何修复它?
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
}
答案1
在我看来,基本问题是引号没有按照您在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
替换为来查看 shell 解析参数后参数的样子(以及因此将发送到远程系统执行的内容)。当我运行这个时: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
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
以前使用过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
而不仅仅是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——它会指出许多常见的错误和不良做法。