转义bash中的特殊字符,case函数

3
我正在创建一个bash脚本。这个脚本将会做与MySQL数据库相同的事情,我已经构建了函数:SELECT、INSERT、UPDATE和DELETE,并且我已经为它创建了登录菜单。现在我需要做的最后一件事是能够在运行脚本时在命令行中插入SQL语句。我已经创建了允许在命令行中输入"--help"运行帮助函数的功能。我也已经创建了在命令行中输入SELECT命令的选项,例如:
./database.sh SELECT name FROM student

这将展示数据库中所有可用名称的完整列表。但我无法让下面的语句运行起来:
例如:
./database.sh SELECT * FROM student

这应该显示可用的完整数据库。但事实并非如此,我已经考虑过转义*字符,但也不起作用。到目前为止,我已经创建了下面的代码片段,脚本将在运行任何函数之前运行它。

if [ -z $1 ]; then
    Inlog
else
    if [ "$1" = "--help" ] ; then
        Help
    else

        case "$*" in
            "SELECT naam FROM student")
                echo "Hieronder is een overzicht van de namen van de studenten die aanwezig zijn in de database."
                echo "------------------------"
                cat $naam_dir
                ;;
            "SELECT nummer FROM student")
                echo "Hieronder is een overzicht van de studentnummers van de studenten die in de database aanwezig zijn."
                echo "------------------------"
                cat $nummer_dir
                ;;
            "SELECT mail FROM student")
                echo "Hieronder is een overzicht van de e-mail adressen van de studenten die in de database aanwezig zijn."
                echo "-----------------------"
                cat $mail_dir
                ;;
            "SELECT \*\ FROM student")
                paste $naam_dir $nummer_dir $mail_dir | expand t-20
            *)
                exit
                ;;
        esac
    fi
fi

我希望有人能帮我转义这些字符。一个SQL查询应该以“;”结尾,到目前为止,我也无法在bash中实现这一点...也许有人有想法。

3个回答

1

看一下 printf 的 -q 开关

示例

$ printf "%q" "'include_path=/path/to/dir'" 
\'include_path=/path/to/dir\'

来自help printf

除了在printf(1)和printf(3)中描述的标准格式规范之外,printf还解释:

  %b    expand backslash escape sequences in the corresponding argument
  %q    quote the argument in a way that can be reused as shell input

在运行脚本之前使用 set -f noglob 命令似乎不起作用。我认为我没有足够的权限,因为我正在一个由学校拥有的 shell 上构建并交付它。 - bryan

0

恐怕你无法让它正常工作。原因是,*;对于shell来说具有特殊含义。例如,*是通配符,匹配当前目录中的所有文件。你必须在命令调用时进行转义/引用,例如:

./database.sh "SELECT * FROM student"

或者

./database.sh SELECT \* FROM student

在 case 语句中,您不必转义 *,因为它已经被 " 引用了。

; 符号有特殊含义(参见 man bash),即 由 ; 分隔的命令将按顺序执行。这意味着您总是可以向命令调用添加 ;,但它不会被传递给被调用的命令作为参数,除非您对其进行转义/引用:

./database.sh SELECT mail FROM student\;

编辑:我刚看到Fredrik的中间编辑。
bash中,可以使用set -f来禁用文件名扩展(即*不会被扩展)。但是这必须在调用shell中执行,不能在脚本中执行。


嗯,好的,我自己也是这么想的,但我的老师说他想要一个数据库脚本,并且查询也可以通过命令行完成。但根据您的评论,我不认为这会起作用。 - bryan
@bryan:为什么不能将整个参数字符串用引号括起来,例如 ./database.sh "SELECT * FROM student"?这样就可以通过命令行执行查询了... - bmk

0
你可以考虑定义自己的术语。而不是在命令行上使用 *,你可以使用 ALL 或其他任何你喜欢的东西。这对用户来说甚至可能更好。

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