Jpp 20.0.0-rc.8
the software that should make you happy
Loading...
Searching...
No Matches
ulib.sh
Go to the documentation of this file.
1#!/usr/bin/env zsh
2#
3#
4# \author mdejong
5#
6#--------------------------------------------------------------------------------------
7#
8# Utility script for zsh library functions.
9#
10#--------------------------------------------------------------------------------------
11
12
13version=1.0
14
15if [[ "$DEBUG" == "" ]]; then
16typeset -i DEBUG=0 # debug level
17export DEBUG
18fi
19
20export DEFAULT_OPTION=-- # default option
21
22if [[ -n "${BASH_SOURCE}" ]]; then
23 export ULIB_DIR=$(dirname "${BASH_SOURCE[0]}")
24elif [[ -n "${ZSH_VERSION}" ]]; then
25 export ULIB_DIR=$(dirname "${(%):-%x}")
26else
27 export ULIB_DIR=$(dirname "${0}")
28fi
29
30# Wild card for any valid detector identifier or run number; to be used as ${~ANY}.
31
32export ANY_ID="[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"
33
34export PI=3.1415926535897931
35
36export BLUE="\e[94m"
37export GREEN="\e[92m"
38export RED="\e[91m"
39export RESET="\e[0m"
40export BOLD="\e[1m"
41
42export TIMESTAMP=\#splitline{}{\#splitline{%d-%m-%y}{\ \ %H:%M}}%F1970-01-01\ 00:00:00
43
44# Array of variable set / unset with set_variable / unset_variable (see below).
45
46typeset -A ULIB_VARIABLES
47export ULIB_VARIABLES
48
49# Array of variables with default values defined with set_variable: or set_variable+ (see below).
50
51typeset -A UDEF_VARIABLES
52export UDEF_VARIABLES
53
54#
55# debug messages
56#
57function fatal() {
58 echo -e $RED`date` FATAL $* $RESET
59 exit 1
60}
61function error() { if (( $DEBUG >= 0 )); then echo -e $RED`date` ERROR $* $RESET; fi }
62function notice() { if (( $DEBUG >= 1 )); then echo -e `date` NOTICE $* ; fi }
63function status() { if (( $DEBUG >= 2 )); then echo -e `date` STATUS $* ; fi }
64function warning() { if (( $DEBUG >= 2 )); then echo -e `date` WARNING $* ; fi }
65function debug() { if (( $DEBUG >= 3 )); then echo -e `date` DEBUG $* ; fi }
66
67
68#
69# Method to check for usage of script.
70#
71# \param 1-N list of command line options
72# \return 0 for option -h; else 1
73#
74function do_usage()
75{
76 for variable in $*; do
77 if [[ "$variable" == "-h!" ]]; then
78 DEBUG=3
79 fi
80 done
81
82 for variable in $*; do
83 if [[ "$variable" == "-h" || "$variable" == "-h!" ]]; then
84 return 0
85 fi
86 done
87
88 return 1
89}
90
91
92#
93# Method to print usage of script and exit.
94#
95# \param 1-N usage
96#
97function usage()
98{
99 echo "$*"
100
101 if (( $DEBUG >= 3 )); then
102 print_array UDEF_VARIABLES
103 fi
104
105 exit
106}
107
108
109#
110# Method to print environment variables.
111#
112function print_env()
113{
114 env
115}
116
117
118#
119# check exit code
120# The last parameter refers to the exit code.
121#
122# \param 1-N message
123# \param N exit code
124#
125function check_exit_code()
126{
127 if (( $argv[-1] )); then
128 error $*
129 exit $argv[-1]
130 else
131 notice $*
132 fi
133}
134
135
136#
137# check exit code alias
138#
139alias CHECK_EXIT_CODE="check_exit_code \$0 \$* \$?"
140
141
142#
143# test quality
144#
145# \param 1 first value
146# \param 2 second value
147#
148function test_equality
149{
150 if [[ "$1" != "$2" ]]; then
151 fatal "<$1> != <$2>"
152 else
153 debug "<$1> == <$2>"
154 fi
155}
156
157
158#
159# Method to check if inside a conda env.
160#
161function has_conda()
162{
163 if [ -n "${CONDA_PREFIX+1}" ]; then
164 return 0
165 else
166 return 1
167 fi
168}
169
170
171#
172# Method to check for CC Lyon.
173#
174# \return 1 for CC Lyon; else 0
175#
176function is_CCLyon()
177{
178 LOCALHOST=`hostname`
179
180 if [[ -n "${LOCALHOST}" && "${LOCALHOST:0:2}" = "cc" ]]; then
181 return 0
182 else
183 return 1
184 fi
185}
186
187
188# Method to check if the local host corresponds to one of the Nikhef computer clusters
189#
190# \return 1 if local host corresponds to one of the Nikhef computer clusters; else false
191#
192function is_CCNikhef()
193{
194 LOCALHOST=`hostname`
195
196 if [[ -n "${LOCALHOST}" && "${LOCALHOST:0:4}" == "stbc" ]]; then
197 return 0
198 else
199 return 1
200 fi
201}
202
203
204#
205# Method to define variable.
206#
207# \param 1 variable
208#
209function define_variable()
210{
211 local variable=$1
212
213 eval export $variable
214}
215
216
217#
218# Method to set variable.
219# Note that a value equal to $DEFAULT_OPTION will not modify the variable.
220#
221# \param 1 variable
222# \param 2-N value(s)
223#
224function set_variable()
225{
226 local variable=$1
227 shift
228
229 if [[ "$*" != "$DEFAULT_OPTION" ]]; then
230 eval export $variable=\"$\*\"
231 fi
232
233 eval ULIB_VARIABLES\[$variable\]=\"\$${variable}\"
234}
235
236
237#
238# Method to set variable.
239# The second variable corresponds to a possible default value.
240# If this variable is defined, the first variable is set to its value
241# else to the given value(s).
242#
243# \param 1 variable
244# \param 2 variable
245# \param 3-N value(s)
246#
247function set_variable:()
248{
249 local variable=$1
250 shift
251
252 local optional=$1
253 shift
254
255 eval value=\"\${$optional:-"$*"}\"
256
257 set_variable $variable $value
258
259 UDEF_VARIABLES[$variable]="$optional -> $value"
260}
261
262
263#
264# Method to set variable.
265# The second variable corresponds to a possible default value.
266# If this variable is defined, the first variable is set to the given value(s)
267# else to an empty value.
268#
269# \param 1 variable
270# \param 2 variable
271# \param 3-N value(s)
272#
273function set_variable+()
274{
275 local variable=$1
276 shift
277
278 local optional=$1
279 shift
280
281 eval value=\"\${$optional+"$*"}\"
282
283 set_variable $variable $value
284
285 UDEF_VARIABLES[$variable]="$optional -> $value"
286}
287
288
289#
290# Method to locally set variable.
291# Note that a value equal to $DEFAULT_OPTION will not modify the variable.
292#
293# \param 1 variable
294# \param 2-N value(s)
295#
296function set_local_variable()
297{
298 local variable=$1
299 shift
300
301 if [[ "$*" != "$DEFAULT_OPTION" ]]; then
302 eval $variable=\"$\*\"
303 fi
304}
305
306
307#
308# Method to unset variable.
309#
310# \param 1 variable
311#
312function unset_variable()
313{
314 local variable=$1
315
316 eval unset $variable
317 eval unset \"ULIB_VARIABLES\[$variable\]\"
318}
319
320
321#
322# Method to print variables.
323#
324# \param 1-N list of variables
325#
326function print_variable()
327{
328 for variable in $*; do
329 eval value=\${$variable}
330 printf "%-20s = %s\n" ${variable} "${value}"
331 done
332}
333
334
335#
336# Method to print associative array.
337#
338# \param 1 array
339#
340function print_array()
341{
342 array=$1
343
344 len=0
345
346 eval keys=\‍(\${\‍(@k\‍)$array}\‍)
347
348 for key in $keys; do
349 if (( ${#key} > $len )); then
350 len=${#key}
351 fi
352 done
353
354 for key in $keys; do
355 eval printf \"%-${len}s = %s\\n\" $key \"\$${array}\[$key\]\"
356 done
357}
358
359
360#
361# Method to check validity of variables.
362#
363# \param 1-N list of variables
364#
365function check_variable()
366{
367 for variable in $*; do
368 eval value=$+${variable}
369 if (( ${value} == 0 )); then
370 fatal "Variable ${variable} not defined."
371 fi
372 done
373}
374
375
376#
377# Method to set array.
378#
379# \param 1 array name
380# \param 2-N values
381#
382function set_array()
383{
384 local variable=$1
385 shift
386
387 eval $variable=\‍($\*\‍)
388}
389
390
391#
392# Method to expand array.
393#
394# Tokens <first>-<last> in the array are exanded to <first> <first + 1> .. <last>
395#
396# \param 1 array name
397#
398function expand_array()
399{
400 eval __BUFFER__=\‍(\$$1\[\*\]\‍)
401
402 eval $1=\‍(\‍)
403
404 for RANGE in $__BUFFER__[*]; do
405 for (( i = ${RANGE%%-*}; $i <= ${RANGE##*-}; i += 1 )); do
406 eval $1+=\‍($i\‍)
407 done
408 done
409}
410
411
412#
413# Method to count directory in ':' separated path list.
414#
415# \param 1 path list
416# \param 2 directory
417#
418function count_directory()
419{
420 eval key=\${$1}
421 eval value=$2
422
423 echo -n $key | tr ":" "\n" | grep "^${value}$" | wc -w
424}
425
426
427#
428# Method to remove directory from ':' separated path list.
429#
430# \param 1 path list
431# \param 2 directory
432#
433function remove_directory()
434{
435 eval key=\${$1}
436 eval value=$2
437
438 if [[ -n "$key" && -n "$value" ]]; then
439 export $1=`echo $key | tr ":" "\n" | grep -v "^${value}$" | tr "\n" ":" | sed 's/:\$//'`
440 fi
441}
442
443
444#
445# Method to remove variable from ':' separated path list.
446#
447# \param 1 path list
448# \param 2 variable
449#
450function remove_variable()
451{
452 eval key=\${$1}
453 eval value=\${$2}
454
455 if [[ -n "$key" && -n "$value" ]]; then
456 remove_directory $1 $value
457 fi
458}
459
460
461#
462# Method to insert directory into ':' separated path list.
463#
464# \param 1 path list
465# \param 2 directory
466#
467function insert_directory()
468{
469 eval key=\${$1}
470
471 if [[ -z "$key" ]]; then
472 export $1=$2
473 elif (( `echo -n $key | tr ":" "\n" | grep "^${2}$" | wc -w` == 0 )); then
474 export $1=$2:${key}
475 fi
476}
477
478
479#
480# Method to check process path.
481#
482# \param 1-N list of process names
483#
484function check_process()
485{
486 for process in $*; do
487
488 local bin=`which $process 2>& /dev/null`
489 debug "Check process ${process}=${bin}"
490
491 if [ -z "${bin}" ]; then
492 fatal "Process ${process} not found."
493 fi
494 done
495}
496
497
498#
499# Method to check file access.
500#
501# \param 1-N list of files
502#
503function check_input_file()
504{
505 if (( $# == 0 )); then
506 fatal "No input file."
507 fi
508
509 for file in `echo $*`; do
510
511 debug "Check input file: ${file}"
512
513 if [[ ! -f ${file} ]]; then
514 fatal "File ${file} not found."
515 elif [[ ! -r ${file} ]]; then
516 fatal "File ${file} not readable."
517 fi
518 done
519}
520
521
522#
523# Method to check file access.
524#
525# \param 1-N list of files
526#
527function check_output_file()
528{
529 for file in `echo $*`; do
530
531 debug "Check output file: ${file}"
532
533 if [[ -f ${file} ]]; then
534 fatal "File ${file} already exists."
535 fi
536 done
537}
538
539
540#
541# Method to reuse file.
542# Note that this method may require user interaction.
543#
544# \param 1 file name
545# \return 1 when absent; else 0
546#
547function reuse_file()
548{
549 if [[ -f $1 ]]; then
550 rm -i $1
551 fi
552
553 if [[ ! -f $1 ]]; then
554 return 1
555 else
556 return 0
557 fi
558}
559
560
561#
562# Get host IP address
563#
564function get_ip_address()
565{
566 if [[ $(uname) == "Darwin" ]]; then
567 arp $(hostname) | cut -d '(' -f 2 | cut -d ')' -f 1
568 else
569 hostname --all-ip-addresses | cut --delimiter=' ' -f1
570 fi
571}
572
573
574#
575# Get process identifier.
576#
577# \param [hostname]
578# \param process name
579# \return PID
580#
581function get_pid()
582{
583 if (( $# == 1 )); then
584 exec pgrep $1
585 fi
586 if (( $# == 2 )); then
587 exec ssh $1 pgrep $2
588 fi
589}
590
591
592#
593# Method to get least significant digit.
594#
595# \param value
596# \return value
597#
598function getLSD()
599{
600 printf "%f\n" `echo $1 | sed -n "s/[+-]\?\‍([0-9]*.\?[0-9]*\‍)[1-9]\‍([0]*.\?\‍)/\1A\2/p" | sed 's/[1-9]/0/g' | sed 's/A/1/'`
601}
602
603#
604# Method to get time.
605#
606function get_time()
607{
608 if [[ $(uname) == "Darwin" ]]; then
609 date +%s
610 else
611 date +%s.%N
612 fi
613}
614
615#
616# Method to start timer
617#
618function timer_start()
619{
620 let "TIMER = $(get_time)"
621}
622
623
624#
625# Method to stop timer
626#
627function timer_stop()
628{
629 let "TIMER = $(get_time) - $TIMER"
630}
631
632
633#
634# Method to print timer
635#
636function timer_print()
637{
638 printf "Elapsed time %1.3f s.\n" $TIMER
639}
640
641
642#
643# Method to print lap time
644#
645function timer_lap()
646{
647 printf "Elapsed time %1.3f s.\n" $(($(get_time) - $TIMER))
648}
649
650
651#
652# Method to convert associative array to list of equations
653#
654# \param 1 associative array
655#
656function make_equation()
657{
658 local array
659
660 typeset -A array
661
662 eval array=\‍(\${\‍(kv\‍)${1}}\‍)
663
664 echo -n "\""
665
666 for key in ${(k)array}; do
667 echo -n "$key = ${array[${key}]}; "
668 done
669
670 echo "\""
671}
672
673
674#
675# Test if associative array has given key.
676#
677# \param 1 associative array
678# \param 2 key
679# \return 1 if present; else 0
680#
681has_key()
682{
683 local var="${1}[$2]"
684
685 echo ${(P)+${var}}
686}
687
688
689#
690# Make communication with process.
691#
692# Note that:
693# - FD_O is the actual file descriptor for writing to actual process and
694# - FD_I is the actual file descriptor for reading from process.
695#
696# \param 1 process name
697# \param 2-N optional argument(s)
698#
699function attach()
700{
701 PROCESS=$1 # process
702
703 shift
704
705 ARGS="$*" # optional arguments
706
707 FIFO_O=/tmp/${PROCESS}_writing.$$ # named pipe for writing
708 FIFO_I=/tmp/${PROCESS}_reading.$$ # named pipe for reading
709
710 rm -f $FIFO_O
711 rm -f $FIFO_I
712
713 mkfifo $FIFO_O # create a new FIFO
714 mkfifo $FIFO_I # create a new FIFO
715
716 eval "exec {FD_O}<>$FIFO_O" # attach file descriptor to FIFO
717 eval "exec {FD_I}<>$FIFO_I" # attach file descriptor to FIFO
718
719 # launch process in background and cleanup afterwards
720
721 eval \‍($PROCESS \
722 $ARGS \
723 < $FIFO_O \
724 > $FIFO_I \&\& \
725 rm -f $FIFO_O \&\& \
726 rm -f $FIFO_I\‍) \&
727}
728
729
730#
731# Remove communication with process.
732#
733# \param 1 file descriptor for writing to process
734#
735function detach()
736{
737 if (( $# == 0 )); then
738 FD=$FD_O
739 else
740 FD=$1
741 fi
742
743 print -u $FD "^D"
744}
745
746
747#
748# Write to attachted prcess.
749#
750function sput()
751{
752 print -u $FD_O "$*"
753}
754
755#
756# Read from attachted prcess.
757#
758function sget()
759{
760 eval read $* <\& $FD_I
761}
762
763
764#
765# alias to kill all child processes at exit of parent process
766#
767alias kill_child_processes_at_exit="trap 'kill_child_processes $$' EXIT"
768
769
770#
771# recursively kill child processes for given parent identifier.
772#
773# \param 1 parent identifier
774#
775kill_child_processes()
776{
777 local pid=$1
778
779 for child in `ps --ppid $pid -ho "%p"`; do
780 kill_child_processes $child
781 done
782
783 if (( $pid != $$ )); then
784 kill -9 $pid >& /dev/null
785 fi
786}
787
788
789alias sftpget="$ULIB_DIR/sftpget.zsh"
790alias sftpput="$ULIB_DIR/sftpput.zsh"