sqlite3 command-line - How to show less/more output - command-line

I am using the sqlite3 command-line programme on Ubuntu.
I'd like to see its output paginated on the screen.
So for example, I'd start it like so :
# sqlite3
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> _
Then, at the sqlite prompt, if I type .help:
sqlite> .help
I see a long 'page' of help info, which comes to rest showing the final few lines on the screen.
I am not a fast reader and so cannot read all that info in just a few milliseconds.
So, how do I ensure that I only see a screenful at a time?
In normal command line parlance this could be piped to | less or | more but, that does not seem to work within this sqlite interactive shell.

It does not seem to have something built-in. However, you can use Cntrl+PgUp and Cntrl+PgDn to move up and down from different pages in a terminal (in Ubuntu is gnome-terminal by default, so that should work).
Also, you can call commands from the shell, like in:
$ echo .help | sqlite3 2>&1 | more
sqlite3 prints the output in stderr, therefore the redirection 2>&1. For SQL commands, you can use:
$ sqlite3 my.db "select * from my_table;" | more
And so on.

From the dbcli collection the sqlite compatible litecli emerged in 2018. It can use either the $PAGER environment variable or a defined pager in ~/.config/litecli/config. As the util offers color support, I set it to less -SniFXR(?).
Another method is to let sqlite3 write to an output file/pipe and use less -f -S /tmp/sqlpipe in a second terminal window or tmux pane to read it. Enable with
.shell mkfifo /tmp/sqlpipe
.output /tmp/sqlpipe
It will look like this.
For not having to repeatedly enter the commands, a ~/.sqliterc can be used to set them at startup. Further formatting improves the output, though in the end litecli is a much more comfortable solution.

You can use sqlitestudio instead which sends output to a window with a scrollbar. https://sqlitestudio.pl/index.rvt

Related

VSCode - How to delete a specific command history in command palette (as opposed to clearing everything)?

I would like to delete several commands from VSCode command palette's "recently used" section, but not clear the entire history. How?
So in Chrome's Omnibar, you can use Shift+del to delete a suggestion. But I cannot find an analogous shortcut in VSCode's command palette.
I also looked for a "meta-command" for this, but I only found Clear Command History in the command palette. I want something like Edit/Manage Command History instead.
Edit: a history file that I can directly edit (analogous to ~/.bash_history for Bash) would also do.
Okay, so this question was upvoted today, which brought it back to my attention. I decided to bite the bullet this time and dug into the nuts and bolts of VSCode's files and found where this history is stored.
TLDR
Modifying the history is doable (obviously, because it has to be stored somewhere), but it's not very practical at all. Unfortunately it will continue to be very difficult, until VSCode implements official support (which may be never). I recommend using the following method ONLY IF you absolutely need a history entry deleted.
The method
Note:
I'm using Code OSS (the debranded build of VSCode) on Linux. The method should be applicable to other OSes, but the specific commands and paths will be different.
This method works on VSCode 1.74.2, the latest version as of 2023-01-04. It may or may not work with future versions.
0. Exit VSCode completely
Obviously.
Check with your resource/task/process manager to make sure VSCode is completely killed. If you're not sure, just reboot.
1. Locate lastSyncglobalState.json
This file contains the command palette history data. On Linux it's located at $XDG_CONFIG_HOME/Code - OSS/User/sync/globalState/lastSyncglobalState.json. On Windows it's probably under a similar path in %APPDATA%. Not sure about MacOS. Copy this file to somewhere convenient.
If you are curious how I discovered this file, I did a search of a command I recently ran using rg in $XDG_CONFIG_HOME/Code - OSS/. Note that you have to search the "programmatic name" of the command, not its display name (e.g. rust-analyzer.reload, not rust-analyzer: Restart server).
2. Extract the relevant data
If you open up lastSyncglobalState.json with a text editor directly, you'll find a Russian doll of escaped JSON. Technically you can do the modification straight from here, but I'm not eating this 💩.
Fortunately jq makes this somewhat easier:
# This is Bash but I think it works on Windows CMD too? Not sure.
jq '.syncData.content | fromjson.storage."commandPalette.mru.cache".value | fromjson.entries' lastSyncglobalState.json > history.json
The extracted history.json should look something like this:
[
{
"key": "rust-analyzer.debug",
"value": 297
},
{
"key": "rust-analyzer.syntaxTree",
"value": 298
},
// more entries...
]
3. Modify
Copy history.json to history-new.json, and simply remove the entries you want to delete from history-new.json. Do not modify history.json; we will need it in a bit.
Check that it's still valid JSON after your edits; in particular make sure that you have not left a trailing comma in the array.
4. Write back
The responsible way to do this is to perform the inverse of step 2, starting from the bottom up, update a field, json-encode, then update the field one level up, json-encode again, etc, until we get to the top level. But that's an enormous pain in the arse to do with jq.
Much easier I think, simply double (triple?) json-encode history-new.json, and perform a textual replacement. This is where the original history.json comes in handy:
# In lastSyncglobalState.json, replace the output of...
jq 'tojson | tojson' history.json
# with the output of...
jq 'tojson | tojson' history-new.json
Note that since the output of jq is quoted, it's necessary to remove the outmost layer of quotes (") on both the search string and the replace string. With rg we can automate this:
jq 'tojson | tojson' history.json | rg '^"(.+)"$' -r '$1'
jq 'tojson | tojson' history-new.json | rg '^"(.+)"$' -r '$1'
Of course there's nothing wrong with doing it manually, or with using sed instead if you want to. Again, just be careful you're not creating invalid JSON.
5. Copy back into VSCode directory
Honestly, you probably want to make a backup of the entire $XDG_CONFIG_HOME/Code - OSS/ directory (or whatever it is on your machine) before doing this. It's probably big I know, but I'm not sure what crazy thing VSCode will do if it finds lastSyncglobalState.json unparseable. Better be safe than sorry.
After you've done that, just copy your modified lastSyncglobalState.json back into $XDG_CONFIG_HOME/Code - OSS/User/sync/globalState/lastSyncglobalState.json and voila.
VSCode terminal uses external shell. For linux the default shell it's bash, for windows it's powershell.
If your terminal shell is powershell, go to C:\Users\john\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline on your file explorer
Visit this link for more details, if the above does not help.

Responding to Multiple Command Line Prompts

I have an exe that runs though Windows Console and prompts for responses for three questions. I created a batch file to contain criteria and would like to automate all three responses to the questions so selecting the bat file runs the data within the batch file.
I need to pass the following criteria
1)machine name
(Enter)
2)password
(Enter)
3)backup
(Enter)
I tried "machinename| exe" and it runs fine, and then brings up the prompt for 2)'s answer. I would like answer all three prompts and then run the exe.
Assuming all inputs are executed via stdin, then either a pipe or redirection should work for all three inputs.
The simplest method is to create a temporary response file and use redirection.
#echo off
>response.tmp (
echo machinename
echo password
echo backup
)
<response.tmp prog.exe
del response.tmp
It would seem it would be easy to use a pipe and get rid of the temp file
(echo machinename&echo password&echo backup)|prog.exe
But there is one problem - the parser inserts a space before each & and the ). This will probably break things.
Note that each side of the pipe is executed via cmd /c, so each side is parsed twice. It is the initial pipe parser that inserts the unwanted space.
The simplest way I have found to prevent the extra space is to delay the appearance of the & so that the parser initially thinks the entire left side is a single ECHO command.
#echo off
setlocal
set "+=&"
echo machinename%%+%%echo password%%+%%echo backup|prog.exe
EDIT
The fact that your program hangs at the password prompt implies that the password is read directly from the console, and not via stdin. In this case, you will need something like the freeware AutoIT utility.

IDA Pro: How to change the virtual segment register T in a script

If I press option/alt-G, IDA shows a dialog which allows me to change the value of the T segment register to 1 to indicate that the following bytes should be interpreted a Thumb code.
I would like to be able to change the value of T in a script.
What script function can I use?
Try
SetRegEx(addr,"T",val,SR_user);
I found this by doing it manually, then clicking File | Produce file | Dump Database to IDC file.. and reading the commands used at the manual process location above.
Then read your idc.idc files to for the syntax of the above command.

Showing the input when using redirection operators in command prompt

Hopefully this is an easy/dumb question.
I am redirecting program input and output to text files in Windows.
Example:
program.exe < in.txt > out.txt
But the text that is inputted from the input file isn't shown in the output file (or screen when not redirecting the output). Is there any way to show it easily? I've tried google but I can't find anything.
Depends what program.exe is doing with the input. You will only see it in the file (or the console if you dont redirect) if program.exe actually writes its output to standard out. If you need to send the input multiple ways (such as to the program and also the screen at the same time) and the program itself doesnt actually make provision for this, you need something like tee - or a real shell like bash.

UNIX tty command and file command?

I am new to UNIX and when I was reading a book about UNIX, I came across following two problems that I didn't understand. I would really appreciate your help.
1) Look up the man page for the file command, and then use it on all files in the /dev directory. Can you group these files into two categories?
2) Run the tty command, and note the device name of your terminal. Now use this device name(/dev/pst/6) in the command cp /etc/passwd /dev/pts/6. what do you observe?
Fair question really... it's so easy for us to take so much for granted.
To read the manual page for the command called file, just type...
man file
...which will present a lot of information that will probably be quite confusing, but you'll get used to this stuff pretty quick if you keep at it. Crucially, file is a program that tries to categorise the files you ask it to. If you type...
file /dev/*
...that will do what the question asked, and invoke file with a list of the files in the /dev/ subdirectory. The list is actually prepared by the "shell" program that you're typing into, which then executes the file program and passes it the list. file then outputs some description of the files. On my computer, and where [SHELL-PROMPT] will be different on your computer, I typed file /dev/* and part of the output looked like:
[SHELL-PROMPT] file /dev/*
...lots of stuff...
/dev/cevt: character special (255/176)
/dev/console: character special (5/1)
/dev/core: symbolic link to `/proc/kcore'
/dev/cpqci: character special (10/209)
/dev/cpqhealth: directory
/dev/crom: character special (255/180)
...lots of stuff...
/dev/md8: block special (9/8)
/dev/md9: block special (9/9)
/dev/mem: character special (1/1)
/dev/mice: character special (13/63)
/dev/mouse0: character special (13/32)
/dev/mptctl: character special (10/220)
/dev/net: directory
/dev/nflog: character special (36/5)
/dev/null: character special (1/3)
/dev/parport0: character special (99/0)
...lots of stuff...
There's a filesystem entry for each directory/file combination (known as a path) in the left column, and file is describing the content in the right. Those descriptions may not make a lot of sense, but you can see that some patterns: some entries are "block special", others "character special", some are directory which implies you may find more files underneath (i.e. ls /dev/net/*). The numbers after "special" files are just operating system identifiers to differentiate the files mentioned. The import of this is that input and output from some devices connected to the computer is being made possible as if the device was a file in the filesystem. That "file" abstraction is being used as a general model for input and output. So, /dev/tty for example is tty - or terminal - device. Any data you try to read from there will actually be taken from the keyboard you're using to type into the shell (in the simple case), and anything you write there will become visible in the same terminal you're typing into. /dev/null is another interesting one: you can read and write from it, but it's an imaginary thing that never actually provides data (just indicates and End-of-File condition, and throws away any data written into it). You can keep reading from /dev/random and it will produce random values each time... good if you need random numbers or file content for encryption or some kind of statistical work.
2) Run the tty command, and note the
device name of your terminal. Now use
this device name(/dev/pst/6) in the
command cp /etc/passwd /dev/pts/6.
what do you observe?
By typing "tty" you can ask for the device representing your terminal...
[SHELL-PROMPT] tty
/dev/pts/11
But, I just said /dev/tty is another name for the same thing, so there's normally no need to use the "tty" program to find this more specific name. Still, if you create a couple terminal windows to your host, and type tty in each, you will see that each shell is connected to a different pseudo-terminal device. Still, each shell - and program run from the shell - can by default also refer to its own terminal input and output device as /dev/tty... it's a convenient context-sensitive name. The command...
cp /etc/passwd /dev/pts/6
...where you replace 6 with whatever your tty program really reported (e.g. 11 in my case), does the same thing as...
cp /etc/passwd /dev/tty
...it just reads the contents of the file /etc/passwd and writes them out on your screen. Now, the problem is that /etc/password looks like a lot of unintelligible junk to the average person - it's no wonder you couldn't make sense of what was happening. Try this instead...
echo "i said hello" > /tmp/hello.file
cp /tmp/hello.file /dev/tty
...and you'll see how to direct some specific, recognisable content into a new file (in this case putting it in the tmp "temporary" directory (the file will disappear when you reboot your PC), then copying that file content back to your screen.
(If you have logged on in two terminal windows, you can even go into one shell and copy the file to the /dev/pts/NN device reported by the other shell, effectively sending a message to the other window. You can even bypass the file and echo 'boo' > /dev/tty/NN. You'll only have permissions to do this if the same userid is logged into both windows.)