在 sqlite3 字符串命令中传递 Bash 参数
Posted
技术标签:
【中文标题】在 sqlite3 字符串命令中传递 Bash 参数【英文标题】:Pass Bash argument in sqlite3 string command [duplicate] 【发布时间】: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,这里适用。
【参考方案1】:
您必须在查询周围使用双引号,以允许bash
识别变量。这意味着您必须正确转义作为 SQL 语句一部分的双引号:
... | for i ... ; do sqlite3 my_db.sqlite "SELECT * FROM \"$i\""; done
【讨论】:
是的!有用。我很接近,我在某个地方读到过,但不幸的是它是针对 mysql 的,所以我认为它不起作用。感谢您的帮助!我会尽快接受答案。以上是关于在 sqlite3 字符串命令中传递 Bash 参数的主要内容,如果未能解决你的问题,请参考以下文章
通过回声管道将python变量(字符串)传递给bash命令[重复]
如何告诉python在将命令传递给bash时忽略一个字符(Python到bash命令SyntaxError:因为{而无效的语法)