Sunday, November 29, 2015

Small and useful bash scripts

A growing collection of scripts and headers for your bash scripts.

Check and exit if a script is already running

This is to prevent multiple running instances of the same script:
test "$(pidof -x \"$(basename $0)\")" != $$ && exit
# or (bash only and protected against spaces in paths):
test $(pidof -x "$(basename $0)") != $$ && exit

Note: ''pgrep -af ' /solar/watts 5' '' is interesting to match a script with its arguments.

Get the full directory name of the script

This works no matter where it is being called from:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Automatically manage cronjob additions and removal of commands

Use command lines to add or remove scheduled jobs in your ''crontab'':
croncmd="/home/me/myfunction start 2> /home/me/myfunction/cron_errors < /dev/null"
cronjob="0 0 * * * $croncmd"
# Add
( crontab -l | grep -v "$croncmd" ; echo "$cronjob" ) | crontab -
# Remove
( crontab -l | grep -v "$croncmd" ) | crontab -

Use pv to get a progress bar with dd

''pv'' can be used in many contexts to provide a progress bar:

dd bs=4M if=image.dd | pv | dd of=/dev/sdz

Re-index a set of files (typically images, to build a timelapse)

This works by extracting the number in their name and add non-significant leading zeros (bash)
for f in ​*​.jpg; do mv "$f" /tmp/$(printf "%05d" ${f//[!0-9]/}).jpeg; done

Bash porocess substitution

This usual case:
sort file1 | uniq >tmp1
sort file2 | uniq >tmp2
diff tmp1 tmp2

Is better done with  process substitution (no temporary file, no subshell, not even pipes):
diff <(sort file1|uniq) <(sort file2|uniq)

How it works is ''<(...)'' is replaced by a ''/dev/fd'' file descriptor as if it was a file (ref.)

Ubuntu: find the biggest installed packages

dpkg-query --show --showformat='${Package;-50}\t${Installed-Size}\n' | sort -k 2 -n | grep -v deinstall | awk '{printf "%.3f MB \t %s\n", $2/(1024), $1}' | tail -50
Then after removing it, ''apt-get clean'' will also purge the package cache (a good thing to free some harddrive space)

Find your serial port attached to USB

This returns devices like ttyUSB (or ttyACM):
find /sys/bus/usb/devices/usb*/ -name tty|sed 's|.*\(tty[^/]\+[0-9]\).*|\1|'

Compute date difference with flexible parametrization (very bashic!)

Here is '''':
set -- "${1:-$(</dev/stdin)}" "${@:2}"
[[ -f "$1" ]] && set -- "$(<$1)" "${@:2}"
echo $( date -d@$(( ( $(date +'%s') - $(date -d "$1" '+%s') ) )) +%s ) 3600 / p | dc

root:~# ./ "2016-08-09 06:03"
This is twenty-seven hours from now to the recorded date.

The second and third very bash-specific line in the script makes it possible to pass the date in other ways. Say you stored a timestamp with ''date +'%Y-%m-%d %H:%M' > last.txt''. Then:

root:~# cat last.txt | ./ 
root:~# ./ last.txt 

Switch my wifi router off when not in use (WR703N TP-link)

Automatic wifi shutdown when idle on a small WRT router

The script below runs on my OpenWRT wifi router (a cheap but effective $20 TP-Link TL-WR703N, which I flashed with OpenWRT -- see the how to here).

It is configured as a wifi router, when switched on.

But when no one connects to it, it will blink its led for a while before it shuts down by itself. So it does not waste useless energy, it is more secure at home and we live in one less wifi network.

Monday, November 16, 2015

Easily count tiny items (200 PCB vias here)

One way to check the number of items I just bought on ebay.

How can I check that there are really 200 vias in these bags?
I bought packs of 200 tiny rivets for vias (or check aliexpress for cheaper and choice). Since I am making my PCB on a mill and I often only use only single-sided PCB copper clads, it gets tricky to solder the headers from below. This is very annoying for headers and Arduino shields for example, as they protrude from below also...

I was somehow able to do it but a proper way is to insert so called PCB "through hole rivets" first. This way, the headers can be conveniently soldered from the top, once they are themselves inserted in the rivets (I wrote about it here).

But such rivets are not cheap (I got 200 of them for $20 on ebay!). I felt I had been cheated on when seeing the small volume it represented. Really 200?