首页 > 解决方案 > 重新计算表达式

问题描述

我想重新评估下面的表达式。执行顺序如下:

export query1="select count(*) from table1 where date='\${file_dt}'"

file_date="20180616"
file_dt=`date -d ${file_date} +'%Y-%m-%d'`
echo $file_dt

>>2018-06-16

echo "$query1"
>>select count(*) from table1 where date='${file_dt}'

我希望结果是

>>select count(*) from table1 where date='2018-06-16'

我试过 eval echo eval 和 eval echo。它似乎不起作用。

请有任何建议。

标签: shell

解决方案


正如BashFAQ #50中所讨论的,代码应该存储在函数中——并且包含稍后要评估的命令替换或参数扩展的字符串是代码。例如:

get_query() { echo "select count(*) from table1 where date='${file_dt}'"; }

file_date=20180616
file_dt=$(date -d "$file_date" +%Y-%m-%d)

get_query

当然,你可以使用realized_query=$(get_query)基于当前的字符串赋值file_dt给一个变量;如果您更改file_dt, 再次调用get_query将根据更新后的值生成一个新查询。


顺便说一句——如果你把它变成一个函数,考虑带外传递日期。例如:

get_query() { echo "select count(*) from table1 where date='$(date -d "$1" +%Y-%m-%d)'"; }
get_query 20180616

...因为date -d调用是函数的一部分,所以您不必担心 SQL 注入:任何可能的输入都不会导致包含文字的值'或对数据库产生不良影响的值。


可以使用eval,尽管有风险。请参阅BashFAQ #48,了解为什么eval最好避免使用基于 的技术;除了通常的安全问题外,这将导致字符串中的任何文字双引号eval被更改为语法双引号,关闭硬编码为eval字符串一部分的语法双引号,否则会导致混乱。

但是,为了完整起见:

# DO NOT DO THIS. Error-prone.

query1="select count(*) from table1 where date='\${file_dt}'"

file_date="20180616"
file_dt=`date -d ${file_date} +'%Y-%m-%d'`

eval "echo \"$query1\""

推荐阅读