【发布时间】:2018-08-23 08:41:05
【问题描述】:
我有以下不起作用的命令:
sqlite3 my_db.sqlite "SELECT name FROM sqlite_master WHERE type = 'table';" | for i in $(cat) ; do sqlite3 my_db.sqlite 'SELECT * FROM "${i}"'; done
为了快速解释一下:下面的第一部分应该从我拥有的 sqlite 文件中检索表名:
sqlite3 my_db.sqlite "SELECT name FROM sqlite_master WHERE type = 'table';"
这部分应该是在标准输出中递归地显示每个表的全部内容:
for i in $(cat) ; do sqlite3 my_db.sqlite 'SELECT * FROM "${i}"'; done
问题是我不知道我应该如何将i 传递给 sqlite 命令。我尝试使用"${i}",但显然它被解释为经典字符串来查找匹配的表名,然后返回Error: no such table: ${i}
我应该如何通过i ?
提前感谢您的帮助。
【问题讨论】:
-
管道到
for i in $(cat)是一种从标准输入读取到变量的奇怪方式。你会经常看到类似while read -r i; do ... -
这是一个等待发生的SQL injection attack,即使您使用了正确的引号。
-
@BenjaminW。使用 while 而不是 for 确实可以改进代码,或者它只是一种更传统的方法。我用你写的while循环试过了,它也有效,但我真的看不出处理时间有什么区别,当我使用for循环时速度是相似的。如果你能解释一下,我总是乐于学习更多东西!
-
@chepner 不用担心此代码不能在线获得。
-
对于初学者来说,
$(cat)在每次迭代中都会创建一个子进程,而read是一个内置的。您还需要进行分词和全局扩展 - 如果您有一个名为*的表,它将扩展到当前目录中的所有文件。看看BashFAQ/001,这里适用。
标签: bash sqlite parameter-passing