gpt4 book ai didi

shell - 在 shell 脚本中扩展变量

转载 作者:行者123 更新时间:2023-12-01 04:16:27 26 4
gpt4 key购买 nike

我有一个需要循环的查询。

query="select '$dbserver' as server;"

while read dbserver username password dbname type
do
mysql -h$dbserver -u$username -p$password $dbname -Be"$query" >> /home/develop/myreport.csv
done < $dblist

以下行正确展开。
mysql -h$dbserver -u$username -p$password $dbname -Be"select '$dbserver' as server;" >> /home/develop/myreport.csv

但是,当我取出查询并将其保存在如上所示的变量中时,它会停止按预期工作并为“dbserver”提供空白值。
上面循环中提到的行不起作用。
如何纠正这个问题?

最佳答案

如果您想要 '$dbserver'在循环内展开的查询中,您可能会这样写:

while read dbserver username password dbname type
do
query="select '$dbserver' as server;"
mysql -h$dbserver -u$username -p$password $dbname -Be"$query"
done < $dblist > /home/develop/myreport.csv

正如最初编写的那样,在将任何值分配给 $dbserver 之前,先评估查询字符串。 ,这就是为什么您在输出中得到空字符串的原因。

请注意,输出重定向仅完成一次 - 在 done 上行而不是每次都在循环中(这意味着您不再需要追加)。

使用 eval 在循环外创建查询通常是你可以做的事情。 .但是,因为 $dbserver的值用单引号括起来,结果证明这很难。如果您使用的 DBMS 允许在字符串周围使用双引号(与 SQL 标准相反),那么这适用于 eval:
query='select \"$dbserver\" as server;'
echo "$query"
while read dbserver username password dbname type
do
echo 1: "$query"
eval echo 2: "$query"
qval=$(eval echo "$query")
echo mysql -h$dbserver -u$username -p$password $dbname -Be"$qval"
done

然后,您可以通过替换 ' " 来调整它以使用单引号' 与 ' '\'' ' 序列:
query='select \'\''$dbserver\'\'' as server;'
echo "$query"
while read dbserver username password dbname type
do
echo 1: "$query"
eval echo 2: "$query"
qval=$(eval echo "$query")
echo mysql -h$dbserver -u$username -p$password $dbname -Be"$qval"
done

然而,那是那种让房间里理智的人尖叫的引述序列——请原谅我大声腾出房间! [...稍后...] 那更好!

解释:
  • 整个字符串在单引号内。
  • 这样的字符串中没有转义字符。
  • 因此,第一个反斜杠只是一个反斜杠。
  • 接下来的 4 个字符是序列 '\'' .
  • 这些引号中的第一个终止当前的单引号字符串。
  • 反斜杠暂停了下一个字符的特殊含义,因此字符串包含来自序列中第二个单引号的实际单引号。
  • 第三个单引号开始一个新的单引号字符串。
  • 因此,在处理第一个反斜杠和引号序列后,字符串包含一个反斜杠和一个单引号。
  • $dbserver 在这一点上只是普通的文本。
  • 然后我们重复前面的序列,以字符串中的第二个反斜杠-引号对结束。
  • 一切正常到最后单引号就行了。
  • eval process 在字符串上运行额外的大量扩展。反斜杠-引号对被替换为仅引号; $dbserver的当前值被插入。然后可以将其作为普通参数传递给命令。
    eval的难点确保您不会出现意外的副作用。这对于 MySQL 来说更加复杂,它使用反引号将用作标记的关键字括起来。该符号与 eval 产生了恶魔般的相互作用。 , 当然。但是,在整个查询周围使用单引号并用反斜杠反引号代替每个反引号,您可以这样做:
    query='select \'\''$dbserver\'\'' as server, \`ls\` as column;'
    echo "$query"
    while read dbserver username password dbname type
    do
    echo 1: "$query"
    eval echo 2: "$query"
    qval=$(eval echo "$query")
    echo mysql -h$dbserver -u$username -p$password $dbname -Be"$qval"
    done

    不过我觉得不推荐。

    关于shell - 在 shell 脚本中扩展变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3572334/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com