我有一个验证表条目的 bash 脚本。最终输出值是 $out,它被插入到 SQL INSERT 语句中,然后附加到 /tmp/crew.txt。虽然 $out 显然是用逗号分隔的,但 /tmp/crew.txt 中生成的 INSERT 语句中的值之间没有逗号。为什么会出现这种情况以及如何解决它,以便我在 /tmp/crew.txt 中有逗号分隔值?
#!/bin/bash
out=290,'02:20:00','02:40:00',20.5,NULL
echo "${out:1}"
290,'02:20:00','02:40:00',20.5,NULL
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ("${out:1}");" >> /tmp/crew.txt
vi /tmp/crew.txt
INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ( 290 '02:20:00' '02:40:00' 20 NULL);
因此 /tmp/crew.txt 中的结果应该是:
INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ( 290,'02:20:00','02:40:00',20,NULL);
为什么会这样,如何解决
从脚本中删除回显的输出和空行会得到以下清理脚本:
通过ShellCheck运行该脚本– shell 脚本分析工具会产生以下错误:
按照建议删除引号可修复该错误,所以现在我们有:
但是运行它仍然不能给出正确的答案,因为
echo "${out:1}"
单引号'
没有存储在 中out
,它们需要被转义:解决这个问题:
注意我已将输出文件名更改为
test.txt
测试:
所以你的脚本的最终固定版本是:
关于调试损坏的脚本的课程到此结束。
假设:您的
IFS
变量包含,
. 该脚本不会更改IFS
,因此非默认值必须已在环境中。This other answer注意到您
${out:1}
在如下所示的行中未引用:未加引号的变量会进行分词和文件名生成。分词是 by
IFS
。未引用${out:1}
的被拆分为多个单词,echo
获取多个参数并打印它们,并用单个空格分隔(因为这是什么echo
,不管IFS
)。如果您
printf
按照建议使用,则更容易判断变量是否被引用:如果你没有双引号这个变量,
printf
会得到多个参数${out:1}
,它会生成多行。然后应该很明显会发生一些分裂。使用echo
它连接它的论点在某种程度上混淆了这个事实。单独的问题:
所需的输出表明您不想要
"${out:1}"
但" $out"
带有前导空格。要在变量中包含单引号,您应该确保 shell 不会删除它们。转义它们(归功于已经提到的答案)或双引号:
对我有用的解决方案是回显以下 INSERT 语句:
无需逃避。但是不确定原因。