【问题标题】:Inserting Linux command output into MySQL within Bash script在 Bash 脚本中将 Linux 命令输出插入 MySQL
【发布时间】:2014-07-24 17:09:19
【问题描述】:

我有一个脚本,它扫描一个 IP 地址以查找一个开放的 FTP 端口,然后将该 IP 地址输入到 MySQL 数据库中。但是,在运行脚本时,我收到以下消息:

“第 1 行的错误 1064 (42000):您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册,了解在 '192.168.1.104 附近使用的正确语法 在第 1 行插入用户 (ip) VALUES (192.168.1.104)'

我已设置数据库并将其命名为“nmapscans”,其中包含名为“users”的表和数据类型为“int(20)”的字段名称“ip”

这是我不完整的脚本:

#!/bin/bash

ipadd=`ifconfig wlan0 | awk '/inet / {print $2}' | cut -d: -f2`
nmap -sV $ipadd -p 21 -oG ftp1 ; cat ftp1 | grep closed > ftp2
cut -d: -f2 ftp2 | cut -d"(" -f1 > ftp3
#cat ftp3


function checkDatabase {
    RESULT=`mysql -u root -pQwerty17 --skip-column-names -e "SHOW DATABASES LIKE             'nmapscans'"`
    if [ "$RESULT" == "nmapscans" ]; then
        echo "Database exists"
    else
        echo "Database does not exist"
    fi
}

checkDatabase && echo $?

echo "INSERT INTO users (ip) VALUES ("100");" | mysql -uroot -pQwerty17 nmapscans;

function input_data { 
    #if [[ checkDatabase ]]
    inputfile="ftp3"
    cat $inputfile | while read ip; do
        echo "$ip"
        echo "INSERT INTO users (ip) VALUES ("$ip");"
    done | mysql -uroot -pQwerty17 nmapscans;
    #fi 
}

input_data && echo $?

if [[ input_data == 0 ]]
    then 
        echo "it worked" && rm ftp1 ftp2 ftp3
    else    
        echo "it failed"
fi
exit

【问题讨论】:

  • 您在 mysql 插入语句之间回显 IP。 Mysql 不知道该怎么办。只需删除 echo "$ip" 行。
  • @FlorinStingaciu 太棒了!那行得通。但是,仍然让我感到困惑的是,当我运行脚本时,input_data 函数的状态代码为 0,但脚本末尾的 if 语句的输出显示“失败”
  • 请看我的回答。

标签: mysql linux bash


【解决方案1】:

您在 mysql insert 语句之间呼应了 IPMysql 不知道该怎么办。只需删除 echo "$ip" 行。

变化:

function input_data { 
    #if [[ checkDatabase ]]
    inputfile="ftp3"
    cat $inputfile | while read ip; do
        echo "$ip"
        echo "INSERT INTO users (ip) VALUES ("$ip");"
    done | mysql -uroot -pQwerty17 nmapscans;
    #fi 
}

到:

function input_data { 
    #if [[ checkDatabase ]]
    inputfile="ftp3"
    cat $inputfile | while read ip; do
        echo "INSERT INTO users (ip) VALUES ("$ip");"
    done | mysql -uroot -pQwerty17 nmapscans;
    #fi 
}

还有关于您关于退货声明的问题。变化:

input_data && echo $?

if [[ input_data == 0 ]]
    then 
        echo "it worked" && rm ftp1 ftp2 ftp3
    else    
        echo "it failed"
fi
exit

到:

input_data 

if [[ $? == 0 ]]
    then 
        echo "it worked" && rm ftp1 ftp2 ftp3
    else    
        echo "it failed"
fi
exit

【讨论】:

  • 效果惊人。感谢您的支持和及时回复。
  • 正确的、惯用的测试成功的方法就是if input_data; then ...甚至只是input_data && rm ftp[123] || echo "it failed" >&2
【解决方案2】:

你只是错过了正确的引用:

    echo "INSERT INTO users (ip) VALUES ('"$ip"');"
    #                                    ^     ^

因此,IP 地址被引用为一个字符串,产生那个(现在有效的)SQL 语句:

INSERT INTO users (ip) VALUES ('192.168.1.104');

【讨论】:

  • 不幸的是,即使在进行了建议的更改后,我仍然收到相同的错误消息。我还将 MySQL 中列的数据类型更改为 char,但仍然没有运气。
  • @UmairK 见我上面的评论。
  • @FlorinStingaciu 感谢 Florin 指出这些不同的问题。顺便说一句,MySQL 如何将192.168.1.104 正确理解为int(20)?显然这里还有一件事我错过了!
【解决方案3】:

至少有两种方法可以向用户显示消息,同时仍然能够将其他人重定向到预期的输出。 cat 这里也不需要。最好不要打扰它。

改为将消息发送到 stderr(默认 &2):

while read ip; do
    echo "$ip" >&2
    echo "INSERT INTO users (ip) VALUES ($ip);"
done < "$inputfile" | mysql -uroot -pQwerty17 nmapscans;

在进程替换中使用其他文件描述符:

while read ip; do
    echo "$ip"
    echo "INSERT INTO users (ip) VALUES ($ip);" >&4
done < "$inputfile" 4> >(exec mysql -uroot -pQwerty17 nmapscans)

最好不要将变量公开以防止分词。它现在可能不适用,但它仍然是一个很好的做法。请注意我是如何修复它的:

echo "INSERT INTO users (ip) VALUES ($ip);"

您也可以选择添加引号:

echo "INSERT INTO users (ip) VALUES ('$ip');"

【讨论】:

    猜你喜欢
    • 2021-03-23
    • 2021-01-17
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    相关资源
    最近更新 更多