首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用here-document时的bash脚本变量分配

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

Stack Overflow用户
提问于 2012-12-15 22:32:20
回答 1查看 1.7K关注 0票数 2

我刚开始使用bash /mysql,但是我发现了大量的帮助,比如阅读抛出的例子和其他人的问题,...but遇到了我自己的问题。每次将文件添加到特定目录时,我都会尝试在MySQL数据库表中插入一行(为此,我使用inotifywait ),下面是我的bash脚本

代码语言:javascript
复制
#!/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具有其缺省值,而不是由$filename表示的字符串

根据我可以得出的结论,变量$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

在哪里可以找到如何将变量传递到查询中的任何帮助都将非常感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-15 22:47:04

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

代码语言:javascript
复制
filename=$(inotifywait --format "%f" -e create /var/www/media2net/torrent)

类似地,

代码语言:javascript
复制
date_field=$(date +"%F:%T")

请注意,您的mysql命令(date_field和注意date_feild)中有一个拼写错误:

代码语言:javascript
复制
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清理文件名,如下所示:

代码语言:javascript
复制
printf -v filename '%q' "$(inotifywait --format "%f" -e create /var/www/media2net/torrent)"

这至少可以转义文件名中可能出现的单引号。请看戈登·戴维森的评论:printf技巧不能阻止所有可能的攻击,所以我真的希望你绝对控制文件的名称!

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

代码语言:javascript
复制
#!/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,这与以空格开头的字符串有关吗?或者其他完全不同的东西?

这是因为当你做像这样的事情时:

代码语言:javascript
复制
whatever= command

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

代码语言:javascript
复制
$ IFS='c' read a b c <<< "AcBcC"
$ echo "$a $b $c"
A B C
$ echo $IFS

$

在您的脚本中,变量filename实际上从未进行过全局设置。您可以通过执行以下操作进行检查:

代码语言:javascript
复制
$ filename= "false"
$ echo "$filename"

$

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

执行此操作时:

代码语言:javascript
复制
filename= inotifywait --format "%f" -e create /var/www/media2net/torrent

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

代码语言:javascript
复制
echo $filename

这相当于

代码语言:javascript
复制
echo

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

希望这能有所帮助。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13893083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档