通过Bash Scripting转义MYSQL命令行

Par*_*roX 15 mysql ssh bash escaping sh

PHP必须mysql_real_escape_string()正确地转义任何可能导致问题的字符.模仿BASH的这种功能的最佳方法是什么?

反正有没有使用bash做准备的mysql语句?这似乎是最好的方式.

我的大多数变量都不会(不应该)有特殊字符,但我给用户完全自由的密码.它可能包含"和"之类的字符.

我可能正在做多个SQL语句,所以我想创建一个接受参数然后运行语句的脚本.这是我到目前为止:

doSQL.sh:

#!/bin/sh

SQLUSER="root"
SQLPASS="passwor339c"
SQLHOST="localhost"

SQL="$1"
SQLDB="$2"


if [ -z "$SQL" ]; then echo "ERROR: SQL not defined"; exit 1; fi
if [ -z "$SQLDB" ]; then SQLDB="records"; fi

echo "$SQL" | mysql -u$SQLUSER -p$SQLPASS -h$SQLHOST $SQLDB
Run Code Online (Sandbox Code Playgroud)

以及使用所述命令的示例:

example.sh:

PASSWORD=$1
doSQL "INSERT INTO active_records (password) VALUES ('$PASSWORD')"
Run Code Online (Sandbox Code Playgroud)

如果密码密码中包含单引号,显然会失败.

Pau*_*ce. 11

在Bash中,printf可以为您逃脱:

$ a=''\''"\;:#[]{}()|&^$@!?, .<>abc123'
$ printf -v var "%q" "$a"
$ echo "$var"
\'\"\\\;:#\[\]\{\}\(\)\|\&\^\$@\!\?\,\ .\<\>abc123
Run Code Online (Sandbox Code Playgroud)

我会留给你判断这是否足够激进.

  • 转义 utf8 字符时会遇到问题,它将为 utf   提供 \302240 ,它会给你带来很多麻烦。 (3认同)

bra*_*blc 6

无论您使用什么引号,都无法逃脱以下构造:

function quoteSQL() {
    printf "FROM_BASE64('%s')" "$(echo -n "$1" | base64 -w0 )"
}

PASSWORD=$1
doSQL "INSERT INTO active_records (password) VALUES ($(quoteSQL "$PASSWORD"));"

# I would prefer piping
printf 'INSERT INTO active_records (password) VALUES (%s);\n' $(quoteSQL "$PASSWORD") | doSQL
Run Code Online (Sandbox Code Playgroud)


hob*_*ave 5

这似乎是在工作中使用错误工具的经典案例。

要实现在 bash 中完成的转义,您还有很多工作要做mysql_real_escape_string()。请注意,mysql_real_escape_string()实际上将转义委托给 MySQL 库,该库考虑了连接和数据库字符集。它被称为“真实”是因为它的前身mysql_escape_string()没有考虑字符集,并且可能被欺骗注入 SQL。

我建议使用具有 MySQL 库的脚本语言,例如 Ruby、Python 或 PHP。

如果您坚持使用 bash,那么请使用MySQL Prepared Statements语法。

  • 准备好的陈述真的会有什么不同吗?在准备语句之前,您仍然需要将值传递给 mysql。 (3认同)