shell

152 readers
1 users here now

Welcome to share all things shell scripting (i.e. bash, zsh) here!

founded 2 years ago
MODERATORS
1
 
 

Someone in this thread suggests zsh can expand 1-char arguments to their long form. But my web search finds nothing on this. Can anyone confirm or deny whether that is true? Source appreciated if true.

Ultimately if zsh has that capability, then I would like to know how it would do that considering nroff (or whatever) does not define a uniform universal syntax to associate a long parameter to its short alias. This is a snip of manpage code from rsync and wget:

.IP "\fB\-\-relative\fP, \fB\-R\fP"
Use relative paths.…
.IP "\fB\-H\fR" 4
.IX Item "-H"
.PD 0
.IP "\fB\-\-span\-hosts\fR" 4
.IX Item "--span-hosts"
.PD
Enable spanning across hosts when doing recursive retrieving.

If zsh really has that capability, it would either have to be a quite sophisticated, or sloppy w/occasional flawed results, IIUC. Or is there a DB that maps long to short args somewhere?

2
 
 

TL;DR → The main problem is coming up with a way to reorder an array non-randomly but without introducing bulky code. Like the effect of shuffling a deck of cards in a deterministic cheating way.


Full background:

I would like to generate reference numbers for letters sent via postal mail. An sqlite db is used to track the sequence numbers (but not the reference numbers). This is the bash code I have so far:

typeset -a symbolset=(a b c d e f g h   j k   m n   p q r s t u v w x y z     2 3 4 5 6 7 8 9)
ln_symbolset=${#symbolset[@]}; # 41 is the answer, not 42
itemseq=$(sqlite3 ltr_tracking.db "select max(counter) from $tbl;")
printf '%s\n' "next letter reference number is: $(date +%Y)-${symbolset[$((itemseq / ln_symbolset))]}${symbolset[$((itemseq % ln_symbolset))]}"

An array is defined with alphanumeric symbols, taking care to eliminate symbols that humans struggle to distinguish (e.g. 1l0o). Then integer div and mod operations produce a two character number which is then prefixed with the year. So e.g. 2024-aa. Just two chars gives more numbers than would ever be generated in one calandar year.

This code mostly satisfies the need. But there’s a problem: a recipient who receives two letters can easily realise how many letters were sent in the time span of the two letters they receive. Most numbers will start with “a” “b” or “c”.

I do not need or want a cryptographic level of security which then leads to ungodly 16 byte numbers. Simplicity¹ is far more important than confidentiality. Just a small tweak to stifle the most trivial analysis would be useful.

One temptation is to simply manually mix up the order of chars in the symbolset array, hard-coded. But then that makes the code less readible. So I probably need to create a 2nd array “symbolseq” which arbitrarily unorders the symbolset array. I say arbitrary and not random because the sequence must be deterministic and static from one execution to the next.

An associative array is one idea:

typeset -A symbolset_lookup_table=(
[a]=k
[b]=3
[c]=s
…

I’m just slightly put off by the fact that it’s not readily evident that the RHS values are all used from the same set as the LHS keys exactly once.

I should probably encode the year as well. This would give a two char year:

printf '%s ' "$(((2024/41) % 41))" "$((2024 % 41))" "→ ${symbolset[$(((2024 / 41) % 41))]}" "${symbolset[$((2024 % 41))]}"

output:
8 15 → j s

(edit)
All the calculations must be easily reversible so a ref number can be converted back into a sequence number for DB queries.

¹ simplicity in both the code and in the numbers generated.

3
 
 

ps auxf | sort -nr -k 4 | head -5

(As I shamelessly lifted this from DistroTube, I may as well go the whole hog and suggest you alias it to mem5)

4
 
 

lsblk -i --tree -o name,fstype,uuid,path,size,fsuse%,fsused,label,mountpoint #bash #code #snippet