In a zsh I want to loop over all files in a configuration files' directory (/etc/myapp/
) to source them. The files should be sourced in order and are named with two leading digits 10-early 40-middle 99-last
. A user without write permission to /etc
should be allowed to extend the list of files and override the global ones. This is done by creating a $HOME/.myapp
directory. The user files should be sourced in order with the global files, i.e. /etc/myapp/10-early $HOME/.myapp/20-rightafter /etc/myapp/40-middle $HOME/.myapp/90-late /etc/myapp/99-last
. A user should also be allowed to override global files, i.e. when $HOME/.myapp/99-last
exists, then /etc/myapp/99-last
should be skipped.
As answerded here and here, I create an array with all the config files and then use basename
on the array (like here) to restrict it to the NN-lllll
part and sort them. Eventually each file gets sourced from $HOME/.myapp
if it exists there, and from /etc/myapp
otherwise.
# https://stackoverflow.com/a/10981499
# https://unix.stackexchange.com/a/26825
thefiles=(/etc/myapp/* $HOME/.myapp/*(N))
# https://stackoverflow.com/a/9516801
uniquified=( $( for f in "${thefiles[@]}" ; do basename $f ; done | sort -V | uniq) )
for f in $uniquified
do
# -r checks if file exists and is readable
if [[ -r $HOME/.myapp/$f ]]
then
source $HOME/.myapp/$f
else
source /etc/myapp/$f
fi
done
Is there a more elegant solution and should I be aware of errors I need to catch?
1 Answer 1
You can combine sort -V | uniq
into sort -uV
.
Note that the -V
flag of sort
doesn't exist in BSD.
Consider replacing it with -n
if that's good enough.
The if
inside the loop can be written more compactly as:
[[ -r $HOME/.myapp/$f ]] && source $HOME/.myapp/$f || source /etc/myapp/$f
You could also replace source
with .
which is equivalent.