La gestione della umask nelle shell tradizionali non e' mai stata flessibile, ma sono tempi in cui sempre piu' spesso ci si trova a lavorare in ambienti condivisi dove, sullo stesso filesystem, coesistono aree private e aree di gruppo.
Sarebbe comodo poter dire alla shell: voglio una umask 022 per i file nella
mia $HOME, ma voglio 007 per la directory /project.
La scuola zshaolin tramanda la seguente tecnica:
# umask per directory # # NOTA: la tabella 'umask_table' e' sequenziale e verra' scelto il primo # match valido, percio' se si vuole impostare una umask per una directory e per # una sua sotto directory bisognera' impostare prima quella della sottodirectory. # # INOLTRE: il path della directory deve essere racchiuso tra apici e puo' contenere # white-space. # # Esempio: # umask_table=( # '~/Work/FooBar' 022 # '~/Work' 011 # ) typeset -A umask_table umask_table=( '~/Work' 007 '~/tmp' 027 '~/ciao ciao' 011 ) chpwd() { local current_umask=$(umask) for dir new_umask in ${(kv)umask_table}; do if [[ "$PWD" == ${~dir}* ]]; then [[ $current_umask == $new_umask ]] && return echo "[zsh] Switching to '$dir' umask: $new_umask" PREVIOUS_UMASK=$current_umask umask $new_umask return fi done if [[ ! -z $PREVIOUS_UMASK ]]; then echo "[zsh] Switching to 'previous' umask: $PREVIOUS_UMASK" umask $PREVIOUS_UMASK unset PREVIOUS_UMASK fi }
Questa tecnica approfitta della special function chpwd di zsh, che, se definita, viene chiamata ogni volta che la working directory viene cambiata.
Esiste anche una tecnica piu' pulita di definire la umask_table, inventata
dagli zshaolin della scuola GRML che
utilizza gli zstyle di zsh; la tecnica funziona cosi':
zstyle ':chpwd:profiles:$HOME/Work(|/|/*)' profile work
Con questa tecnica il lookup della corretta usermask non sara' un loop, ma una
singola chiamata a zstyle, tipo:
zstyle -s ":chpwd:profiles:${PWD}" profile profile || profile='default'