使用here-document时bash脚本变量分配

时间:2012-12-15 14:32:20

标签: mysql linux bash eof

我是bash / mysql的新手但是我已经找到了大量的帮助阅读示例和其他人的问题...但是遇到了我自己的问题。 我试图在每次将文件添加到特定目录时向MySQL数据库表插入一行(对于我使用的是inotifywait),无论如何这里是我的bash脚本

#!/bin/bash

while true; do
        filename= "false"
        filename= inotifywait --format "%f" -e create /var/www/media2net/torrent
        date_field= date +"%F":"%T"
        mysql --host=localhost --user=root --password=admin Media2net << EOF
        insert into video (title, description, url_video, upload_date)
                values('testing','default_description','$filename', '$date_feild');
        EOF
        echo $filename
done

由此我已经使用echo验证变量$filename在bash脚本结束时被正确保存但是当我查看表中的条目时,url_video列具有默认值而不是{{1表示的字符串}}

从我的结论来看,变量$filename不会通过EOF传递 我已经尝试了http://www.dba-oracle.com/t_access_mysql_with_bash_shell_script.htm

以及

Using shell script to insert data into remote MYSQL database

任何帮助,我可以找到如何将变量传递给查询将非常感激

1 个答案:

答案 0 :(得分:3)

在您的示例中,filename设置为空字符串(请注意=符号后面的空格!)。你需要

filename=$(inotifywait --format "%f" -e create /var/www/media2net/torrent)

类似地,

date_field=$(date +"%F:%T")

小心,您的mysql命令(date_field并注意date_feild)中有拼写错误:

mysql --host=localhost --user=root --password=admin Media2net <<EOF
insert into video (title, description, url_video, upload_date)
values('testing','default_description','$filename', '$date_field');
EOF

现在我希望您控制文件名。想象一个包含单引号的文件名,例如hello'howdy。您的查询中存在问题。更糟糕的是,一个邪恶的用户放置一个名为whatever','something'); evil_mysql_command; whatever的文件,你将执行邪恶的命令!一种可能性是使用printf来清理文件名:

printf -v filename '%q' "$(inotifywait --format "%f" -e create /var/www/media2net/torrent)"

这至少会逃避可能出现在文件名中的单引号。请参阅Gordon Davisson的评论:printf技巧不会阻止所有可能的攻击,所以我真的希望你绝对控制文件的名称!

所有这些建议都会产生以下脚本:

#!/bin/bash

while true; do
    printf -v filename '%q' "$(inotifywait --format "%f" -e create /var/www/media2net/torrent)"
    date_field=$(date +"%F:%T")
    mysql --host=localhost --user=root --password=admin Media2net <<EOF
    insert into video (title, description, url_video, upload_date) 
    values('testing','default_description','$filename', '$date_field');
    EOF
    echo "$filename"
done

修改。

在评论中回答您的问题:

  

为什么脚本正确地将$filename回显到我的终端但没有正确发送到MySQL,这是否与字符串以空格开头有关?还是别的什么呢?

那是因为你做了类似的事情:

whatever= command

然后将变量whatever设置为空字符串,并执行命令command(将whatever变量设置为环境变量)。如,

$ IFS='c' read a b c <<< "AcBcC"
$ echo "$a $b $c"
A B C
$ echo $IFS

$

在您的脚本中,变量filename实际上从未全局设置。你可以这样做检查:

$ filename= "false"
$ echo "$filename"

$

环境变量filename设置为空字符串然后使用该环境变量启动命令false(恰好存在),我们就完成了。

执行此操作时:

filename= inotifywait --format "%f" -e create /var/www/media2net/torrent

将变量filename设置为空字符串,然后使用inotifywait ...作为环境变量执行命令filename(但inotifywait并不真正关心关于它)。 这就是你在终端上看到的内容!这是该命令的输出。然后你可能看到一个空行,这是

的输出
echo $filename

相当于

echo

因为变量filename扩展为空字符串。

希望这有帮助。