やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

SQLite3ドットコマンド(.shell .system)

 シェルコマンドを実行する。

成果物

.help shell

sqlite3 :memory: ".help shell"
sqlite3 :memory: ".help system"
.shell CMD ARGS...       Run CMD ARGS... in a system shell
.system CMD ARGS...      Run CMD ARGS... in a system shell

 .shell,.systemどちらも同じ。

.shell, .system

uname

sqlite3 :memory: ".shell uname -a"
sqlite3 :memory: ".system uname -a"
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux

 カーネル名の取得。

uname -s
Linux

対話モードでread

.shell { read -p "なんか入力すれば?> " SOME_INPUT; echo "入力結果: ${SOME_INPUT}"; }
なんか入力すれば?> 
なんか入力すれば?> aaaaaaaaaaaaaaaaaaaaaaaa
入力結果: aaaaaaaaaaaaaaaaaaaaaaaa

 問題は.shellコマンド1回の実行あたり1プロセスであること。異なるプロセス間ではシェル変数の共有ができない。

.shell read -p "なんか入力すれば?> " SOME_INPUT
なんか入力すれば?> 
なんか入力すれば?> bbbbbbbbbbbbb
.shell echo "入力結果: ${SOME_INPUT}"
入力結果: 

 でない。シェル変数SOME_INPUTが1回目のコマンド終了時に死んだから。解決するためには同一プロセス内で実行すべき。そのために{ ... }を使う。

.shell出力結果は.outputで指定不可

sqlite3 :memory: \
".output '/tmp/work/tmp.txt'" \
".shell uname -s" \
".output stdout" \
"select readfile('/tmp/work/tmp.txt');"
Linux
cat /tmp/work/tmp.txt



 .shellで実行するシェルコマンドの出力先は、シェルコマンド内で指示すること。

sqlite3 :memory: \
".shell uname -s > /tmp/work/tmp.txt" \
".output stdout" \
"select readfile('/tmp/work/tmp.txt');"
Linux
cat /tmp/work/tmp.txt
Linux

.shell出力結果をパラメータにセットできなかった……

  1. カーネルLinuxuname -sコマンドから取得する
  2. 1をパラメータ@kernel_nameにセットする

 という予定だった。

失敗ログ

sqlite3 :memory: \
".param init" \
".shell uname -s | tr -d "\n" > /tmp/work/tmp.txt" \
"insert into sqlite_parameters values('@kernel_name', (select SUBSTR(cast(readfile('/tmp/work/tmp.txt') as text), 1, length(cast(readfile('/tmp/work/tmp.txt') as text))-1)));" \
".param list"
kernel_name 'Liux'

 なぜnが消えている? LiuxでなくLinuxが期待値なのだが……。

 キャストしないとblob型になるっぽい。

sqlite3 :memory: \
".param init" \
".shell uname -s | tr -d "\n" > /tmp/work/tmp.txt" \
"insert into sqlite_parameters values('@kernel_name', readfile('/tmp/work/tmp.txt'));" \
".param list"
kernel_name X'4C6975780A'

 キャストしたらnが消えて末尾に改行がでた……。

sqlite3 :memory: \
".param init" \
".shell uname -s | tr -d "\n" > /tmp/work/tmp.txt" \
"insert into sqlite_parameters values('@kernel_name', cast(readfile('/tmp/work/tmp.txt') as text));" \
".param list"
kernel_name 'Liux
'

 lengthで末尾の1字を消した。だが相変わらずnが消えたまま。

sqlite3 :memory: \
".param init" \
".shell uname -s | tr -d "\n" > /tmp/work/tmp.txt" \
"insert into sqlite_parameters values('@kernel_name', (select SUBSTR(cast(readfile('/tmp/work/tmp.txt') as text), 1, length(cast(readfile('/tmp/work/tmp.txt') as text))-1)));" \
".param list"
kernel_name 'Liux'

 ファイル書込前で改行を消そうとしても無駄。

sqlite3 :memory: \
".param init" \
".shell uname -s | tr -d "\n" > /tmp/work/tmp.txt" \
"insert into sqlite_parameters values('@kernel_name', cast(readfile('/tmp/work/tmp.txt') as text));" \
".param list"
kernel_name 'Linux
'

 ファイル読込後に改行を削除しようとREPLACE関数を試みるもダメ。

sqlite3 :memory: \
".param init" \
".shell uname -s | tr -d "\n" > /tmp/work/tmp.txt" \
"insert into sqlite_parameters values('@kernel_name', (select REPLACE(cast(readfile('/tmp/work/tmp.txt') as text), '\n', ' ')));" \
".param list"
kernel_name 'Linux
'

 SUBSTRだと長さを指定せねばならない。

sqlite3 :memory: \
".param init" \
".shell uname -s | tr -d "\n" > /tmp/work/tmp.txt" \
"insert into sqlite_parameters values('@kernel_name', (select SUBSTR(cast(readfile('/tmp/work/tmp.txt') as text), 1, 3)));" \
".param list"
kernel_name 'Lin
'

 長さを負数にしたら成功しないか? と期待するもダメ。

sqlite3 :memory: \
".param init" \
".shell uname -s | tr -d "\n" > /tmp/work/tmp.txt" \
"insert into sqlite_parameters values('@kernel_name', (select SUBSTR(cast(readfile('/tmp/work/tmp.txt') as text), 1, -1)));" \
".param list"
kernel_name ''

 もし負数が使えたなら、-2とすることで末尾から1文字前までの範囲を指定できることを期待していた。だが使えない。

sqlite3 :memory: \
".param init" \
".shell uname -s | tr -d "\n" > /tmp/work/tmp.txt" \
"insert into sqlite_parameters values('@kernel_name', (select SUBSTR(cast(readfile('/tmp/work/tmp.txt') as text), 1, -2)));" \
".param list"
kernel_name ''

 ならTRIMは? ダメ。つまり空白文字じゃない? 改行ではない? もしやEOFか?

sqlite3 :memory: \
".param init" \
".shell uname -s | tr -d "\n" > /tmp/work/tmp.txt" \
"insert into sqlite_parameters values('@kernel_name', (select TRIM(cast(readfile('/tmp/work/tmp.txt') as text))));" \
".param list"
kernel_name 'Liux
'

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux

前回まで