2026-02-03 14:35:26 -07:00
2026-02-03 13:26:07 -07:00
2026-02-02 22:20:54 -07:00
2026-02-02 22:03:20 -07:00
2026-02-02 22:03:20 -07:00
2026-02-03 14:35:26 -07:00
2026-02-03 13:50:18 -07:00

Select Option

Creates a tui selector based off of stdin. printf '1\n2\n3' | select_option will create a selector for a, b, c. Navigate with F-keys, j/k, or arrow keys, then press enter on your selection. This will print out the selected option to stdout.

Usecases

Selecting a drive from the system

lsblk -lno type,name | grep part | awk '{ print "/dev/" $2 }' | select_option

If you use the wrapper you can then pipe your output to more commands:

lsblk -lno type,name | grep part | awk '{ print "/dev/" $2 }' | ./wrapper.sh | xargs -I% echo Mounting %...

What about bash's select?

I didn't know this existed when I wrote this program. But on the plus side they aren't exact copies of eachother. Bash's select works like:

select x in a b c; do
    echo "selected: $x"
    break
done

Where it just creates a little text menu:

1) a
2) b
3) c
#?

Of which you can input your number.

This has some issues:

  1. You can select values that are out of bounds. Meaning that your script to be defensivly programmed.
  2. You can't use vim keys to move around.
  3. It is harder to implement into a stream since you have to turn your agruments into an array. (Seems to be designed for scripts, not one-liners.)
  4. I didn't make the program.

Interestingly, I found the same trick they use to allow for menus to be printed but also pipe the output. By putting them menu on stderr instead of stdout you can have a menu that doesn't get yoinked by the pipe's reidrection.

Recipies

Note: I have the program wrapper script on my $PATH and have the wrapper script renamed to opts.

Show all directories, entering the selected one.

cd $(ls -la | grep dr | awk '{ print $9 }' | opts)

Show all partitions, mounting the selected one at /mnt.

sudo mount $(lsblk -lno type,name | grep part | awk '{ print "/dev/" $2 }' | opts) /mnt

You could even do the filtering after the fact, to give the user more info.

sudo mount $(lsblk | opts | awk '{ print $1 }') /mnt

(But this would allow you to select bad data.)


Choose what video codec to change all the videos in the current directory to.

OPTS="mpeg4\nh265\nh264"
SEL=$(printf $OPTS | opts)

for x in $(ls); do
	ffmpeg -i $x -v:c $SEL ${x}-enc.mp4
done
Description
Languages
Rust 96.3%
Shell 3.7%