非交互式的SQLite3在Bash脚本中的使用

32

我看到很多展示如何使用sqlite3交互式shell的例子,例如:

$ sqlite3
$ sqlite3> SELECT * from x;

但我正在寻找一种用bash脚本创建SQLite3数据库中表格的方法,即非交互式。

例如,以下内容似乎不起作用,它仍然是交互式的:

#!/bin/bash
sqlite3 test.db  "create table n (id INTEGER PRIMARY KEY,f TEXT,l TEXT);"
sqlite3 test.db  "insert into n (f,l) values ('john','smith');"
sqlite3 test.db  "select * from n";

例如创建表tbl1(one varchar(10),two smallint); - zon7
2
没有需要唤醒的东西,SQLite3不使用服务器/守护进程 - Sir Athos
谢谢你的信息,很有用。另外一件事,我的回答实际上并不起作用 - 它仍然是交互式的。 - Alexander Mills
2
尝试将最后的分号移动到双引号内部,而不是外部。 - Matt Zabojnik
4个回答

29

2
好的,我确认这个可以工作 - 只要test.db存在,这是非交互式的。 - Alexander Mills
1
在最后一个命令中,您可能打算将分号放在引号内,否则它将成为Bash的命令(在这种情况下不起作用)。 - Paddy Landau
1
谢谢Paddy,我修复了那个分号的位置。 - Alexander Mills

28

虽然以上方法应该是可行的,但我认为最好不要多次调用sqlite3,因此我认为以下方法更可取:

#!/bin/sh
sqlite3 test.db <<EOF
create table n (id INTEGER PRIMARY KEY,f TEXT,l TEXT);
insert into n (f,l) values ('john','smith');
select * from n;
EOF

请注意,除非您真正需要使用bash,否则出于可移植性的原因,应该选择"/bin/sh"作为您的shebang。


3
我认为你不应该使用/bin/sh作为shebang:通常sh是符号链接到bash的,所以任何在bash中有效但在sh中无效的代码直到有人在某个非常古老的平台(例如Solaris 9)上运行你的代码时才会被发现,因为这些平台上sh和bash确实存在差异,并且会抛出错误。 - Cheiron
1
@Cheiron:你提到的在使用/bin/sh shebang脚本中未被注意到的bashisms一点也没错,但我仍然不同意。我不知道在Linux世界中将/bin/sh链接到/bin/bash有多常见,但这并不是普遍的情况。例如,在Lubuntu(目前唯一可用的Linux系统)中,/bin/sh链接到/bin/dash而不是/bin/bash。更重要的是,并非所有的世界都是Linux。除了“永恒”的平台外,像我一直在使用的现代、广泛使用的系统FreeBSD根本没有/bin/bash。我坚持我的建议。 - varro
1
FreeBSD的参数不是/bin/bash的参数吗?Dash不是sh,bash也不是sh,zsh也不是sh,所以我认为应该选择实际使用的shebang。如果我创建一个bash脚本并将/bin/sh放在其上方,我实际上无法测试它是否在sh上运行,因为我的系统上/bin/sh是符号链接到/bin/bash的,所以我应该将/bin/bash作为shebang,对吧? - Cheiron
2
我没有30年的经验,但我不敢假设我的bash可以在sh上运行而无法进行检查。我也不认为学习你的手艺等同于不犯错误,尤其是在疲劳时。我喜欢可移植性,但我需要至少一个测试系统来支持每个平台,否则我无法确认代码是否真正得到了支持。所以只要我没有sh,我更喜欢使用/bin/bash,以免给出虚假承诺:我只能测试bash,所以我放置/bin/bash。 - Cheiron
3
@MikeS 那么为什么我可以将 /bin/sh 写成 shebang,然后使用 [[?在 sh 中不存在 [[。因此,当 sh 是 shebang 时,实际上我是在撒谎,因为它只会在你将 sh 符号链接到类似于 bash 的 shell 时才能运行。这就是我的观点:sh 已经过时且令人困惑,所以坚持使用您知道它可以正常工作的 shell。 - Cheiron
显示剩余4条评论

12

您可以使用 -batch 选项来禁用交互模式:

sqlite3 -batch test.db "create table n (id INTEGER PRIMARY KEY,f TEXT,l TEXT);"

1
无法使用cmd内部命令工作,比如sqlite3 -separator ',' -cmd ".import file.csv' tmp" -batch tmp.db - e-info128
1
@e-info128 不确定你是否已经得到了答案,但是 cat << EOF | sqlite3 tmp.db <newline> .import file.csv tmp EOF 对我有效。 - shriek

3

这也可以工作

sqlite3 "${DB_FILE_NAME}" < data_model.sql
sqlite3 "${DB_FILE_NAME}" < dml.sql

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接