SQLite User Forum

.exit 0 and .quit in file ignored when running ’sqlite3 -init file file.sqlite’
Login

.exit 0 and .quit in file ignored when running 'sqlite3 -init file file.sqlite'

(1.1) By hruodr on 2024-05-30 18:16:10 edited from 1.0 [source]

I have sqlite3 command from FreeBSD 14.0's Package sqlite3-3.45.1,1.

If I have a file 'file.sql' containg SQL commands (or nothing) and 
at the end '.exit 0' or '.quit', then running

sqlite3 -init file.sql file.sqlite

leaves me at the sqlite3 prompt, sqlite3 does not exit.

If I end the file with '.exit 1', it exits.

The only thing I wanted to do is to generate 'file.sqlite' inside a script.

Any hint what is happening?

Should I compile a newer version of sqlite3 and try?

Thanks
Rodrigo

EDIT:

For my purpose, the following works:

sqlite3 -init file.sql file.sqlite .quit

An sh "here-document" does not work for me, I want the command inside
a Makefile.

But I am still curious about an answer to my original question.

(2) By Stephan Beal (stephan) on 2024-05-30 18:15:12 in reply to 1.0 [link] [source]

Should I compile a newer version of sqlite3 and try?

As a general rule that's a good policy to follow, but the behavior you find disagreeable is also in the trunk. Whether it's a feature or a bug is unclear to me, but recall that it's been brought up before over the years.

The only thing I wanted to do is to generate 'file.sqlite' inside a script.

If you don't need a specific -init file for that (and i'm not sure why you would), you just have to pipe sqlite3 the commands/input you want.

Show us what you're trying to do and someone will likely present a way to do it without relying on an explicit -init script.

(3.4) By hruodr on 2024-05-30 18:34:06 edited from 3.3 in reply to 2 [link] [source]

Your solution 

cat file.sql | sqlite3 file.sqlite

works. Thanks!Is it documented?

I edited my original question, there is other solution. And more details 
of what I want. Perhaps part of the problem is that my knowledge of 
'make' is not more that what is in Feldmans Article of 1978.

The SQL commands are in a big file, that is why I need an init file,
or just to pipe it to sqlite3.

But as said, I am curious about this unexpected behaviour.

(4) By Stephan Beal (stephan) on 2024-05-30 18:33:15 in reply to 3.2 [link] [source]

Is it documented?

See www:/cli.html.

my knowledge of 'make' is not more that what is in Feldmans Article of 1978.

GNU make has come a long way since then. The other flavors of make, not so much.

I am curious about this unexpected behaviour.

It's come up before but i did take part in, and don't recall, the discussions about why it's that way.

(5) By hruodr on 2024-05-30 18:44:04 in reply to 4 [link] [source]

The problem with Unix make is that every line goes in a sh interpreter,
but what about a command with many lines like a sh "here document"?

And the sqlite3 commands beginning with "." must end with a line.

Sure there is a way with modern "make" versions, I hope at least elegant ...

(6) By Adrian Ho (lexfiend) on 2024-05-31 04:38:31 in reply to 5 [link] [source]

Depends on your definition of "elegant". Here's one way to do it in GNU Make, defining a multi-line variable:

$ cat Makefile
define s
sqlite3 <<'EOS'
.mode table
.headers on
select value, sqrt(value), '$(MAKE)', '$@' from generate_series(100000,1000000,100000);
EOS
endef
export s

all:
	@eval "$$s"

$ make
+---------+------------------+----------------------------------------------------+-------+
|  value  |   sqrt(value)    | '/Library/Developer/CommandLineTools/usr/bin/make' | 'all' |
+---------+------------------+----------------------------------------------------+-------+
| 100000  | 316.227766016838 | /Library/Developer/CommandLineTools/usr/bin/make   | all   |
| 200000  | 447.213595499958 | /Library/Developer/CommandLineTools/usr/bin/make   | all   |
| 300000  | 547.722557505166 | /Library/Developer/CommandLineTools/usr/bin/make   | all   |
| 400000  | 632.455532033676 | /Library/Developer/CommandLineTools/usr/bin/make   | all   |
| 500000  | 707.106781186548 | /Library/Developer/CommandLineTools/usr/bin/make   | all   |
| 600000  | 774.596669241483 | /Library/Developer/CommandLineTools/usr/bin/make   | all   |
| 700000  | 836.660026534076 | /Library/Developer/CommandLineTools/usr/bin/make   | all   |
| 800000  | 894.427190999916 | /Library/Developer/CommandLineTools/usr/bin/make   | all   |
| 900000  | 948.683298050514 | /Library/Developer/CommandLineTools/usr/bin/make   | all   |
| 1000000 | 1000.0           | /Library/Developer/CommandLineTools/usr/bin/make   | all   |
+---------+------------------+----------------------------------------------------+-------+

(7) By hruodr on 2024-05-31 08:21:19 in reply to 6 [link] [source]

Thanks, that looks good!

I found other solutions.

'make -j 1' forces FreeBSD's make to send all lines to the same sh instance,
Plan9's mk that is in Plan9 Port does it in standard way.

With that, I can put the 'here document' directly below the target.

(8) By Kees Nuyt (knu) on 2024-05-31 08:41:12 in reply to 5 [link] [source]

A simplified, shortened, snippet from one of my make files:

shadh:
        @sqlite3 ./adh.sqlite \
".mode columns" \
".width -5 -5 20 20 -5 200" ".nullvalue '-'" \
".output tmp/shadh6.txt" \
".print UA by id" \
"SELECT * FROM v_uaghits ORDER BY 5" \
".output" \
".mode line" \
".print hits by most recent, details" \
"SELECT * FROM v_log1 ORDER BY 1 DESC" \
>tmp/shadh2.txt
        @less -S tmp/shadh[0123456].txt
        @rm -f tmp/shadh[0123456].txt

sh is only invoked 3 times here. The sqlite3 invocation is a longish one-liner, but readable by using the '\' line continuation that make supports.

(9.1) By Stephan Beal (stephan) on 2024-05-31 09:19:07 edited from 9.0 in reply to 7 [link] [source]

With that, I can put the 'here document' directly below the target.

FWIW, i think the more conventional way to do that is with temp files. Something along the lines of this completely untested code (noting also the lack of hard tab characters):

Makefile:

mytmp: Makefile
  { \
    echo "This is my SQL."; \
    echo "There are many like it "; \
    echo "but this one is mine."; \
  } > $@

foo.db: mytmp
  sqlite3 $@ < $<

(10) By hruodr on 2024-05-31 11:07:23 in reply to 8 [link] [source]

Thanks! Now we are back to sqlite3, namely to its documentation.

'sqlite3 --help' shows that the invocation is:

Usage: sqlite3 [OPTIONS] [FILENAME [SQL]]

I did not know that sqlite3 accepts as 'SQL' many arguments!!!!

But with this thread I learned also something more about make,
thanks to Adrian and Stephan!

The original question on the behaviour of -init file remains open.