0

我正在尝试编写一个 Bash 脚本来从脚本中构造的字符串运行 MySQL 查询。我已经能够构造查询字符串,并且在回显时看起来是正确的。我可以将它剪切并粘贴到 shell 命令行中并运行。但是,我基本上需要将查询结果缩减为 OK 或 CRITICAL 等单词。没有其他的。当我尝试将查询结果保存到 bash 变量时,我得到:

mysql:未知选项'-2'

如果我剪掉 grep 并剪掉代码,我会得到mysql --help结果。所以,它不喜欢我的 mysql 字符串,但我不知道为什么。帮助?

顺便说一句-运行 CentOS 6.3

alert=`mysql myDB -e "select value from config_table where name=\"ach_alert_time\"\G" | /bin/grep value: | /bin/cut -f2 -d:`
echo $alert  #Brings back 18,50,00

sql="mysql myDB -e 'select if(count(*) > 0,\"CRITICAL\",\"OK\") as STATUS from xyz_batch where timestamp > concat(date(now()),\" \",maketime("$alert"))\G' | /bin/grep OK  | /bin/cut -f2 -d:"
echo $sql # mysql myDB -e 'select if(count(*) > 0,"CRITICAL","OK") as STATUS from xyz_batch where timestamp > concat(date(now())," ",maketime( 18,50,00))\G' | /bin/grep OK | /bin/cut -f2 -d

status=`$sql`

# Whoops!
# mysql: unknown option '-2'

echo $status
4

3 回答 3

1

问题是,当您作为命令运行时,它会进行分词、文件名扩展等,而不考虑可能包含$sql的任何引号。$sql而且它不会处理管道和其他 shell 元字符。例如,如果您位于包含文件foo和的目录中bar,那么:

cmd="echo '     *     ' | grep baz"
$cmd

将打印' bar foo ' | grep baz——它不会保留空格,它会将 扩展*为文件列表,并将|andgrep视为echo.

您可以使用命令eval "$sql"而不是仅使用以下命令来解决此问题$sql

status=`eval "$sql"`

但您可能需要重新评估您的设计。也许有更好的方法来实现你想要的?


编辑添加:您说您正在脚本中构建查询,但您实际上是否需要将整个命令存储在变量中?像这样的东西:

sql="select if(count(*) > 0,\"CRITICAL\",\"OK\") as STATUS from xyz_batch where timestamp > concat(date(now()),\" \",maketime("$alert"))\G"
status=`mysql myDB -e "$sql" | /bin/grep OK  | /bin/cut -f2 -d:`

不会有这个问题,因为 then$sql只是一个参数,所以你不需要 Bash 对它做任何特别的事情。

于 2012-08-24T18:04:30.917 回答
1

你可以让自己发疯,试图让每件事都正确逃脱。将其分解为可管理的步骤:

# Multiple lines allowed, for readability. Inside single quotes, no
# escaping needed.
sql_template='select if (count(*) > 0, "CRITICAL", "OK") as STATUS
  from xyz_batch
  where timestamp > concat( date( now() ), " ", maketime("%s"))\G'

# Bash 4 only
printf -v sql_stmt "$sql_template" "$alert"
# Bash 3 equivalent
# sql_stmt=$( printf "$sql_template" "$alert" )

status=$( mysql myDB -e "$sql_stmt" | awk -F: '/OK/ {print $2}' )
于 2012-08-24T18:37:40.653 回答
0

双码有问题。

sql="mysql myDB -e 'select if(count(*) > 0,\"CRITICAL\",\"OK\") as STATUS from xyz_batch where timestamp > concat(date(now()),\" \",maketime("$alert"))\G' | /bin/grep OK  | /bin/cut -f2 -d:"

用。。。来代替

sql=`mysql myDB -e 'select if(count(*) > 0,\"CRITICAL\",\"OK\") as STATUS from xyz_batch where timestamp > concat(date(now()),\" \",maketime("$alert"))\G' | /bin/grep OK  | /bin/cut -f2 -d:`
于 2012-08-24T18:05:50.057 回答