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