Tidbits 1

by , on
last update by Peter Ludikovsky, on

Just some small stuff I found that don’t warrant a full standalone blog post.

Background shell functions

Something I found out just today is that bash/zsh can run shell functions as background jobs, just like if they were regular programs. For example

function bgf {
    str=$1
    slp=$(( $RANDOM % 9 + 1 ))
    echo "bgf $str: sleeping $slp"
    sleep $slp
    echo "bgf $str: done"
}
bgf "FUNC1" &
bgf "FUNC2" &
bgf "FUNC3" &
wait

will produce

bgf FUNC1: sleeping 5
bgf FUNC2: sleeping 1
bgf FUNC3: sleeping 7
bgf FUNC2: done
bgf FUNC1: done
bgf FUNC3: done

This should help bring down the run time of my homegrown backup script by a bit.

zsh (non-)randomness

Trying the above with zsh will produce an interesting effect: all calls will sleep for the same amount of time. The reason is that zsh intentionally uses a copy of the RNG state for all sub-shells. So any sub-shell should change the RNG state by assigning to RANDOM, e.g.

# Linux
RANDOM=$( date +%s%N )
# *BSD with GNU coreutils installed
RANDOM=$( gdate +%s%N )
# Pretty much always
RANDOM=$( perl -MTime::HiRes=gettimeofday -MPOSIX=strftime -e \
  '($s,$us) = gettimeofday();
   printf "%s.%06d\n", strftime("%s", localtime($s)), $us;' \
)

FreeBSD ZFS block sizes

On the topic of *BSD: Thanks to MacLemon I now know that the FreeBSD ZFS implementation doesn’t support the ashift zpool parameter. Since this defines the basic block size for the pool, can’t be changed after creation, and is taken to be whatever the disk reports (even if wrong) this could lead to less-than-optimal performance. Solution? Use gnop to fix the reported size.