在shell变量中转义单引号

4
我编写了一个Bash脚本来向sqlite数据库中插入值。命令如下:
sqlite3 ${db_name} "insert into ${table_name} (${column1},${column2}) values ('$f1','$f2');"

这个命令在f1变量中包含单引号时会出现问题

# e.g f1="I'm just kidding"
# the command reported error
Error: near "m": syntax error

请问如何在变量内转义单引号?欢迎提供建议,谢谢!


1
你知道这个脚本可能存在SQL注入的风险吗? - Oren
我的建议?使用一种编程语言。 - Ignacio Vazquez-Abrams
嗨@Oren,实际上我不擅长SQL,我只是编写了脚本,以便手动逐个添加条目到数据库中。 - Dien Nguyen
如果这个脚本只是用于个人使用,那么我想这样写也没问题。但是,如果有其他人可能会使用这个脚本,那么现在的编写方式会让你的数据库容易受到攻击。解决这个问题的方法是输入验证,但在脚本中实现起来非常困难。在这种情况下,@IgnacioVazquez-Abrams 的建议是一个不错的选择。 - Oren
最常见的可能是*如何在单引号字符串中转义单引号*(2009年,26个回答,1380个赞)。请参考此答案以获取相对简单的语法。 - Peter Mortensen
3个回答

5

为了在SQL中转义单引号,你需要将其加倍(https://www.sqlite.org/faq.html#q14):

$ f1="I'm just kidding"
$ echo "${f1//\'/''}"
I''m just kidding
$ f2="no single quotes"
$ echo "${f2//\'/''}"
no single quotes

所以
sqlite3 ${db_name} "insert into ${table_name} (${column1},${column2}) values ('${f1//\'/''}','${f2//\'/''}');"

4
从Bash中,您可以使用${varname//x/y}来替换变量varname中所有的x为y。
sqlite3 ${db_name} "insert into ${table_name} (${column1},${column2}) values ('${f1//\'/\'}','${f2//\'/\'}');"

将任何 ' 替换为 ',尽管 @ignacioVazquez-Abrams 给出了最好的答案,因为 PHPPerlPython 的实现都有帮助净化输入的模块。


嗨 @peteches,谢谢你的回答。它返回“Bad substitution”。 - Dien Nguyen
1
抱歉,我匆忙地处理了一下,并且将转义反斜杠放错了位置。现在已经进行了编辑,应该可以工作了。如果还不行的话,可能是你的Bash版本不支持替换,我记不清它是在哪个版本中引入的。 - peteches

-1

你可以使用\

f1="I\'m just kidding"

嗨 JoaoBiriba,f1 变量是从文件中读取的,所以它可以是任意字符串。在执行脚本之前,我们应该对文件进行预处理吗? - Dien Nguyen
所以你可以使用sed预处理文件,例如:sed 's/<pattern>/<replacement>/' - GioLaq
我不认为这样行得通,至少从命令行来说是不行的。echo $f1返回的是I\'m just kidding(包括反斜杠)。在Ubuntu上测试过,使用的是Bash 4.4.20版本。 - Peter Mortensen
在单引号之后,唯一具有特殊含义的是另一个单引号。 - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接