2 ############################################################
4 # author: devenkong(18151155@qq.com)
6 ############################################################
7 # Copyright (C) 2022- Free Software Foundation, Inc.
8 # This configure script is free software; the Free Software
9 # Foundation gives unlimited permission to copy, distribute
11 ############################################################
13 # stdio is a string output shlib. some times, we need
14 # to output on tty console, some times we need to output in
15 # log file, and somtimes we want to output string in pipe
16 # file. stdio provide different output channel.
17 # in linux kernel, there are functions outputing debug
18 # info by different level, or different name. stdio referenced
19 # from it, and provide info/warn/err/log output function.
20 # string output function in stdio is used to solve the
21 # problem, that output string in while loop with redirect or
22 # pipe connection. the stdout is changed to a non-named pipe,
23 # the defsult string output is redirected it the pipe. use
24 # function in stdio.shlib, it will output string on tty,
25 # or other place we invoked.
26 # there is another problem in redirected while loop,
27 # the loop code maybe running as an sub-process, and the cmd
28 # exit is exited from the sub-process, but not the program.
29 # we will find that the variavles cann't be uodated in
30 # loop code as a sub-process. use 'while do done < <()',
31 # instead of ',cat - | while do done'. this makes the loop
32 # code run in current process.
33 # system cmd echo output string without newline by -e
34 # option, but some version needn't this optiin. functions
35 # in stdio.shlib output without newline, and this can be
36 # setted. stdio.shlib also provide functiins to add prefix
37 # and surfix in a string output. we use err() invoking with
38 # defsult "[err]: " prefix.
39 # some usefull function is seperated in dbgout.shlib,
40 # so that stdio.shlib can be compact.
41 # it's the feature for string output, and some console
42 # operation like color char display, term setting, is in
43 # another shlib term.shlib.
44 # the string content can be orgnized as some format,
45 # as we usually use. and dbglogview is designed to dispatch
46 # the formated string. function event, invoke timestamp,
47 # a variable data output, can be dispatched from dbglog
48 # string, it will display dbglog string more beautifull.
49 ############################################################
54 # - @ *adding channel_config, setting channel paramter.
55 # @ the default string output cmd echo, sometimes run with -e, and sometimes not.
56 # use an alias to making compatiable.
57 # @ add signal process function, and recieve cmd to setting paramter by other
58 # program. it's usefull for a deamon program, to set debug string output range.
60 # !@ all the dispaly function will clear BASH_REMATCH when it is invoked. so, do not
61 # invoke string display function in =~ operation, or impove it.
62 # !@ when string output function invoke in set -x state, it will display many cmd in
63 # string output function. maybe disable it by set +x.
64 # !@ there is a bug for string output. echo -ne "-e" treat "-e" as a paramter.
65 # fileter first output char by "-", and output seperatly.
69 # this cmd enable alias feature in script. it is disabled in default.
70 shopt -s expand_aliases
72 # init ROOTFS used in current lib.
73 if [[ ! -d $ROOTFS ]]; then
74 TMP_DIR
=`dirname $(which ls)`/..
75 TMP_DIR
=`cd $TMP_DIR; pwd; cd - > /dev/null`
76 ROOTFS
=${ROOTFS:-$TMP_DIR}
81 # global variable re-init if this shlib has been loaded.
82 # invoke this before 'uniqlib'
87 # the code below only load in one time.
91 ##############################
92 # section: public comment info
93 ##############################
96 # %param-global-comment%
97 # dbgout-str: string used as debug output.
98 # func-name: such as dbgout, debout<N>, logout, info, warn, err, crash.
103 ##############################
104 # section: variable define
105 ##############################
109 # get free file handler id.
111 __get_file_top_valid_id
()
116 for (( i
=$
((i-1
)); i
>0; i--
)); do
117 [[ ! -e /proc
/self
/fd
/$i ]] && echo $i && return
122 # init channels when shlib is loaded in new pogram.
124 init_tty_n_prog_channel
()
127 vch_null
=$
(__get_file_top_valid_id
)
128 eval "exec $vch_null<>/dev/null"
130 # init stdio channel of main process
131 vch_progstdin
=$
(__get_file_top_valid_id
)
132 eval "exec $vch_progstdin<&0"
133 vch_progstdout
=$
(__get_file_top_valid_id
)
134 eval "exec $vch_progstdout>&1"
135 vch_progstderr
=$
(__get_file_top_valid_id
)
136 eval "exec $vch_progstderr>&2"
138 # get tty dev for current program
139 f_ttyout
=$
(ps
-p $$
-o tty |
tail -n 1 | cut
-d ' ' -f1)
140 # echo -ne "f_ttyout=$f_ttyout\n"
141 f_ttyout
="/dev/$f_ttyout"
142 # echo -ne "f_ttyout=$f_ttyout\n"
145 if [[ ! -e $f_ttyout ]]; then
148 if [[ ! -e $f_ttyout ]]; then
153 # open tty dev, and bind to a fd.
155 vch_ttyout
=$
(__get_file_top_valid_id
)
157 eval "exec $vch_ttyout<>$f_ttyout"
158 [[ $?
!= 0 ]] && vch_ttyout
=$vch_null
161 # ls -l /proc/self/fd/
165 # stdio.shlib global variable init.
166 # it should be invoked every time program launched. if stdio.shlib
167 # is loaded in cmd enviroument, use it to re-init in program init.
172 # the variable defined and initialized here would be effective in current process.
175 # save main process id of current program.
176 # it should be initialized in program init. and it is used for progexit, the function
177 # is exit from program, not sub-process in script code.
178 declare -g -x STDIO_PROG_ID
=$$
181 # logical-channel define
183 # stdout is handler 1
184 # stderr is handler 2
185 # those three channel are not defined in variable.
188 # those variables should not be defined with -x option.
190 declare -g vch_progstdin
=0
191 declare -g vch_progstdout
=1
192 declare -g vch_progstderr
=2
193 declare -g vch_dbgout
=2
194 declare -g vch_logout
=2
195 declare -g vch_liberr
=2
196 declare -g vch_ttyout
=1
197 declare -g vch_null
=2
200 # when the string is outputed by using cmd 'tee', it uses file name but not file handler.
201 # so, it defines log file name variable here.
205 declare -g f_ttyout
=/dev
/null
# the default ttyout is null dev, and it will be re-initialized in every program.
208 # directory define for ppe file and log file storage.
209 # if the file name paramter in channel init function contsin path info, it eill be resetted.
210 declare -g dbgout_file_path
=
211 declare -g logout_file_path
=
212 if [[ ! -v def_dbglogout_file_path
]]; then
213 declare -g -r readonly def_dbglogout_file_path
=$ROOTFS/var
/log
/dbglogout
/
216 # file, file name string with accessiable path.
217 # file_name, just only a file name.
218 # file_path, path of file.
221 # set initial file name string for pipe file and log file.
222 # the surfix of pipe file is .pipe, the surfix of log file is .1.log or .2.log.
225 declare -g dbgout_file_name
=${dbgout_file_name-$(basename $0)}.pipe
# dbgout
226 declare -g logout_file_name
=${logout_file_name-$(basename $0)}.log
228 declare -g dbgout_sfx
=".dbgout"
229 declare -g logout_sfx
=".log"
232 # string prefix & surfix
233 # used for string hi-light display, color-full display.
234 # dbgouthex and other dbgout_xxx(), and logout, and ttyout, does not use sfx and pfx.
236 declare -g STROUT_PFX
=""
237 declare -g LIBERR_PFX
=""
238 declare -g DBGOUT_PFX
=""
239 declare -g INFO_PFX
=""
240 declare -g WARN_PFX
="\033[1m[warn]: \\033[0m"
241 declare -g ERR_PFX
="\033[31m[err]: \\033[0m"
242 declare -g CRASH_PFX
="[crash]: "
243 declare -g NEWLINE_SFX
="\n"
244 declare -g DBG_NEWLINE_SFX
=""
247 # paramter of debug and log.
251 # getting size of file is an io operstion, use string line count to limit log
252 # file size is more suitable.
259 dbgout_default_level
=3
260 dbgout_output_level
=3
264 # todo: if a file is sourced, $0 means the file sourced, not the main program.
265 # maybe use BASH_ variable is better.
267 PROG_STR
=`basename $0`
269 # program channel info init.
270 init_tty_n_prog_channel
279 # global variable init function invoking.
280 # invoke GVAR_INIT if it is running at first time.
285 ##############################
286 # section: private function
287 ##############################
290 # exit from main process of program.
297 # todo:hilight should be reviewed.
298 alias dbg_param_chk
="
299 if [[ \$DBG_PARAM =~ \"d\" ]]; then
303 if [[ \$dbgout_output_level -lt \$dbgout_default_level ]]; then
307 if [[ \$DBG_PARAM =~ \"H\" ]]; then
309 DBG_PARAM=\${DBG_PARAM//H/h}
318 log_row_cnt
=$
(( log_row_cnt
++ ))
319 if [[ $log_row_cnt -ge $max_log_lines ]]; then
321 if [[ $f_logout =~
".2$logout_sfx" ]]; then
322 name
=${f_logout%%.?.log}
323 rm $name.1$logout_sfx
324 mv $name.2$logout_sfx $name.1$logout_sfx
325 touch $name.2$logout_sfx
327 logout_file_name
=${logout_file_name//\.1$logout_sfx/\.2$logout_sfx}
328 f_logout
=${f_logout//\.1$logout_sfx/\.2$logout_sfx}
334 # set debug out port, and hi-light display mode
335 # dbgset <enable|disable> <value>
343 if [[ "$1" == "enable" ]]; then
344 DBG_PARAM
="${DBG_PARAM//d/}"
345 alias dbgout
="dbgoutd"
347 DBG_PARAM
="d${DBG_PARAM}"
353 if [[ "$1" == "enable" ]]; then
355 DBG_PARAM
="h${DBG_PARAM}"
358 DBG_PARAM
="${DBG_PARAM//h/}"
363 if [[ "$1" == "enable" ]]; then
364 DBG_PARAM
="${DBG_PARAM//$2/}"
366 DBG_PARAM
="$2${DBG_PARAM}"
374 ##############################
375 # section: public function
376 ##############################
379 # fsyntax: libstrout <dbgout-str>
380 # fdesc: used for string output in shlib.
384 [[ $output_disable_list =~
"libstrout" ]] && return
386 # todo: output string in vch_libout channel
388 if [[ $logout_disable_list =~
"libstrout" ]]; then
389 echo -ne "$LIBERR_PFX$@$NEWLINE_SFX" >&$vch_progstdout
391 echo -ne "$LIBERR_PFX$@$NEWLINE_SFX" |
tee -a $f_logout >&$vch_progstdout
397 # fsyntax: liberr <dbgout-str>
398 # fdesc: err info in shlib.
402 [[ $output_disable_list =~
"liberr" ]] && return
404 # todo: output string in vch_libout channel
406 if [[ $logout_disable_list =~
"liberr" ]]; then
407 echo -ne "$LIBERR_PFX$@$NEWLINE_SFX" >&vch_liberr
409 echo -ne "$LIBERR_PFX$@$NEWLINE_SFX" |
tee -a $f_logout >&vch_liberr
415 # fsyntax: info <dbgout-str>
416 # fdesc: normal application information string output.
420 [[ $output_disable_list =~
"info" ]] && return
422 if [[ $logout_disable_list =~
"info" ]]; then
423 echo -ne "$INFO_PFX$@$NEWLINE_SFX" >&$vch_progstdout
425 echo -ne "$INFO_PFX$@$NEWLINE_SFX" |
tee -a $f_logout >&$vch_progstdout
431 # fsyntax: warn <dbgout-str>
432 # fdesc: warn output, but use same channel with info.
436 [[ $output_disable_list =~
"warn" ]] && return
438 if [[ $logout_disable_list =~
"warn" ]]; then
439 echo -ne "$WARN_PFX$@$NEWLINE_SFX" >&$vch_progstdout
441 echo -ne "$WARN_PFX$@$NEWLINE_SFX" |
tee -a $f_logout >&$vch_progstdout
447 # fsyntax: err <dbgout-str>
448 # fdesc: err string output to stderr.
452 [[ $output_disable_list =~
"err" ]] && return
454 if [[ $logout_disable_list =~
"err" ]]; then
455 echo -ne "$ERR_PFX$@$NEWLINE_SFX" >&$vch_progstderr
457 echo -ne "$ERR_PFX$@$NEWLINE_SFX" |
tee -a $f_logout >&$vch_progstderr
464 # fdesc: trace output in err channel.
468 err
"`echo ${FUNCNAME[*]} | rev | tr ' ' '\n' | rev | sed -E \"s/\n/()=>/g\"`"
472 # fsyntax: crash <dbgout-str>
473 # fdesc: output trace string, and exit from main process.
477 [[ $output_disable_list =~
"crash" ]] && __progexit
479 if [[ $logout_disable_list =~
"crash" ]]; then
480 echo -ne "$CRASH_PFX`echo ${FUNCNAME[*]} | rev | tr ' ' '\n' | rev | sed -E \"s/\n/()=>/g\"`$NEWLINE_SFX" >&$vch_progstderr
481 echo -ne "$CRASH_PFX$@$NEWLINE_SFX" >&$vch_progstderr
483 echo -ne "$CRASH_PFX`echo ${FUNCNAME[*]} | rev | tr ' ' '\n' | rev | sed -E \"s/\n/()=>/g\"`$NEWLINE_SFX" |
484 tee -a $f_logout >&$vch_progstderr
485 echo -ne "$CRASH_PFX$@$NEWLINE_SFX" |
tee -a $f_logout >&$vch_progstderr
492 # fsyntax: dbgout <dbgout-str>
493 # fdesc: debug string output. output level can be setted.
497 [[ $output_disable_list =~
"dbgout" ]] && return
502 if [[ $dbg_color_set == 1 ]]; then
503 echo -ne "$dbg_fr_color$dbg_bg_color"
507 if [[ $logout_disable_list =~
"dbgout" ]]; then
508 echo -ne "$DBGOUT_PFX$@$DBG_NEWLINE_SFX" >&$vch_dbgout
510 echo -ne "$DBGOUT_PFX$@$DBG_NEWLINE_SFX" |
tee -a $f_logout >&$vch_dbgout
516 # fsyntax: logout <dbgout-str>
517 # fdesc: log string output with size limit.
521 echo -ne "$@$NEWLINE_SFX" >> $f_logout
528 # fsyntax: ttyout <dbgout-str>
529 # fdesc: force to output string in tty device in current session.
533 printf "$@$NEWLINE_SFX" >&$vch_ttyout
537 # fsyntax: error <dbgout-str>
538 # fdesc: output err info to tty device, and can not be redirected. it is used for emergency
543 [[ $output_disable_list =~
"err" ]] && return
545 if [[ $logout_disable_list =~
"err" ]]; then
546 Â Â Â
printf "$ERR_PFX$@$NEWLINE_SFX" > $f_ttyout
549 printf "$ERR_PFX$@$NEWLINE_SFX" |
tee -a $f_logout > $f_ttyout
554 # fsyntax: dbgoutd <dbgout-str>
555 # fdesc: just only output string for debug without log.
556 # the purpose of this function is just for debug info.
557 # if the output string is usefull for program, change
558 # it to other output functions then.
559 # it's the temp code for program. delete thos function
560 # invoking when the program is published, or define a
561 # blank cmd like 'dbgoutd () {}' in your code after
566 echo -ne "$DBGOUT_PFX$@$DBG_NEWLINE_SFX" >&$vch_dbgout
570 # testing cmd for alias cmd parameter.
571 # echo input-string | { std0=123; exec 123<&0; { var=$(cat -); read $var <&$std0; echo "var=$var"; echo "$var=${!var}"; } <<< "aaa"; }; echo $aaa
575 # fsyntax: readln <var-name>
576 # fdesc: get line data from stdin to the specified var.
577 # the default cmd read does not output blanks
578 # at the beginning of lines.
587 read -d \$'\n' -r \$(cat -) <&\$stdio_std0
592 if [[ \$ret_aS98s == 0 ]]; then
603 # fsyntax: input <var-name>
604 # fdesc: input data from current stdin to specified var. var name is given
605 # though stdin, so, before redirect stdin, save it to another fd.
613 read -d $'\x00' -r \$(cat -) <&$stdio_std0
620 # fsyntax: var=$(pause <var-name> <promt-str> [<def-value>])
621 # fdesc: output with promt info, wait for string input by user. if DEF_INPUT is true,
622 # read operation will be skipped. it's like a single step feature.
626 echo -ne "$2" >&vch_progstdout
628 if [[ -n $3 && $DEF_INPUT == "true" ]]; then
633 read -u $vch_progstdin -r $1
635 [[ -n $3 ]] && [[ -z ${!1} ||
${!1} == "$'\n'" ]] && $1=$3
640 # fsyntax: stdin <var>
641 # fdesc: get data in var from program stdin. this cmd is improved
642 # with IFS setting to read ' ' at the beginning of a string line.
643 # eg: read abc <<< " aaa", $abc is 'aaa' without blank prefix.
644 # others, it append -r arguments to read string include '\'.
646 # alias input="read -u $vch_progstdin -r"
651 read -d $'\n' -r $(cat -) <&$vch_progstdin
656 # fsyntax: stdout <str>
657 # fdesc: output string data to stdout.
659 alias stdout
="echo -ne"
662 # fsyntax: <cmd> | dataout
663 # fdesc: a compatiable interface.
668 # fsyntax: var=$(datain) 或 datain | <cmd>
669 # fdesc: a compatiable interface. read command will filter
670 # chars. '\' char, ' ' at the beginning of a line, and other
671 # un-printable chars.
673 alias datain
="cat - "
677 # fsyntax: set_output_prefix <func-name> [pfx-str]
679 # func-name: logout/dbgout/info/warn/err/crash
680 # pfx-str: orefix for different function output.
681 # fdesc: set different prefix string in different function.
696 if [[ "strout liberr dbgout info warn err crash" =~
$1 ]]; then
699 warn
"specify a valid output function name in \"strout liberr dbgout info warn err crash\" by param.\n"
704 # fsyntax: set_auto_newline [newline-sfx]
705 # fdesc: set surfix in every output string.
713 # fsyntax: dbgout_set_auto_newline <newline-sfx>
714 # fdesc: output string surfix in dbgout.
716 dbgout_set_auto_newline
()
722 # fsyntax: dbgout_set_default_level <level>
723 # fdesc: set default output level which is used in dbgout.
725 dbgout_set_default_level
()
727 dbgout_default_level
=$1
731 # fsyntax: dbgout_set_output_level <level>
732 # fdesc: set debug string output level.
734 dbgout_set_output_level
()
736 dbgout_output_level
=$1
740 # fsyntax: set_output_mask <func-name> [enable|disable]
741 # fdesc: set enable/disable for dbgout/info/warn/err/errtrace/crash, developer
742 # didn't need to comment string output function one by one.
747 output_disable_list
=""
751 if [[ "strout liberr dbgout info warn err crash logout" =~
$1 ]]; then
752 if [[ -z $2 ||
$2 == "disable" ]]; then
753 output_disable_list
="$output_disable_list$1 "
754 elif [[ $2 == "enable" ]]; then
755 output_disable_list
=${output_disable_list//$1 /}
758 warn
"specify a valid output function name in \"strout liberr dbgout info warn err crash\" by param.\n"
763 # fsyntax: set_logout_mask <func-name> [enable|disable]
765 # func_name: dbgout/info/warn/err/errtrace/crash
766 # fdesc: set log output in different string output function.
771 logout_disable_list
=""
775 if [[ "strout liberr dbgout logout info warn err crash" =~
$1 ]]; then
776 # set channel of logout for logout() disable.
777 if [[ $1 == "logout" ]]; then
778 if [[ -z $2 ||
$2 == "disable" ]]; then
779 init_channel
logout "/dev/null"
780 elif [[ $2 == "enable" ]]; then
781 init_channel
logout "$logout_file_name"
787 if [[ -z $2 ||
$2 == "disable" ]]; then
788 logout_disable_list
="$logout_disable_list$1 "
789 elif [[ $2 == "enable" ]]; then
790 logout_disable_list
=${logout_disable_list//$1 /}
793 warn
"specify a valid output function name in \"strout liberr dbgout logout info warn err crash\" by param.\n"
798 # fsyntax: set_log_limit <max-log-lines>
799 # fdesc: set log output line limit count.
808 # fsyntax: dbgout_printinfo
809 # fdesc: print variable used in this shlib.
813 [[ $output_disable_list =~
"dbgout" ]] && return
818 echo "vch_dbgout=$vch_dbgout"
819 echo "f_logout=$f_logout"
820 echo "logout_file_path=$logout_file_path"
821 echo "log_row_cnt=$log_row_cnt"
822 } |
tee -a $f_logout >&$vch_dbgout
826 # fsyntax: duplicate_channel <dst-channel> <src-channel>
827 # fdesc: duplicate channel.
831 local src_ch_name_str
832 local dst_ch_name_str
834 [[ -z $2 ]] && echo -ne "[failed] init_channel() failed, path of \"$path\" is not existing.\n" >&2 && return 1
836 src_ch_name_str
=vch_
$1
837 dst_ch_name_str
=vch_
$2
838 [[ ! "dbgout logout progstdin progstdout progstderr ttyout null" =~
${!src_ch_name_str} ]] && echo -ne "[failed] duplicate_channel() failed, name of \"${!src_ch_name_str}\" is not valid channel.\n" >&2 && return 2
839 [[ ! "dbgout logout progstdin progstdout progstderr" =~
${!dst_ch_name_str} ]] && echo -ne "[failed] duplicate_channel() failed, path of \"${!dst_ch_name_str}\" is not valid channel.\n" >&2 && return 2
841 eval $dst_ch_name_str=${!src_ch_name_str}
843 if [[ $1 == "logout" ]]; then
844 f_logout
=`readlink /proc/self/fd/${!dst_ch_name_str}`
847 if [[ $1 == "dbgout" ]]; then
848 f_dbgout
=`readlink /proc/self/fd/${!dst_ch_name_str}`
852 __logfile_name_fix
()
857 # append number id if it is no number id.
858 if [[ ! $logout_file_name =~
".1.$logout_sfx" && ! $logout_file_name =~
".2.$logout_sfx" ]]; then
859 logout_file_name
=${logout_file_name%%$logout_sfx}.1.log
860 if [[ -n ${logout_file_path} ]]; then
861 f_logout
=$logout_file_path/${logout_file_name}
863 f_logout
=${logout_file_name}
868 if [[ -f $f_logout ]]; then
869 size
=$
(stat
$f_logout |
grep -e "Size:")
873 if [[ ! $size =~
[^
0-9] ]]; then
874 log_row_cnt
=$
((size
/ 30))
881 # if .2.log is existing, get it's size to update log_row_cnt
882 if [[ -f $f_logout ]]; then
883 size
=$
(stat
$f_logout |
grep -e "Size:")
887 if [[ ! $size =~
[^
0-9] ]]; then
888 log_row_cnt
=$
((size
/ 30))
899 # fsyntax: init_channel <channel-name> <file-path>|<file-hd>
901 # channel-name: logout, dbgout, progstdout, progstdin, progstderr, stdout, stdin, stderr.
902 # set /dev/null if no param specified.
903 # file-path: file name string, maybe with path prefix. if ext-name is same as $dbgout_sfx,
904 # output is pipe file.
905 # setting for dbgout or logout:
906 # @ file name without ext-name, and the file is not a device name, append corresponding
908 # @ if file name with path is valid, save path in var.
909 # @ if file name string without path, use the default path.
910 # @ if the file is stored in pwd, set the name like './file'.
911 # file-hd: an opened fd.
913 # fdesc: init and config logical-channel to actual output device. init channel with serial, net,
914 # and other device by device file name, or file handler. invoke physical device paramter setting
915 # before channel init. eg:serial or net.
923 local path
=${2:-'/dev/null'}
926 # no channel specified, all channel would be setted with /dev/null
927 if [[ -z $name ]]; then
930 vch_progstdin
=$vch_null
931 vch_progstdout
=$vch_null
932 vch_progstderr
=$vch_null
937 # no valid file name specified.
938 [[ -z ${path##*/} ]] && echo -ne "[failed] init_channel() failed, file of path \"$path\" does not contain file name.\n" >&2 && return 1
941 # invoke call-back function for unknown device. or invoke device init before this function.
942 if [[ "dbgout logout liberr progstdin progstdout progstderr" =~
$name ]]; then
943 if [[ "$path" =~
[^
0-9] ]]; then
945 # the specified file is opened as an idle handler.
948 # save file path and name, used to output log string.
949 if [[ "dbgout logout" =~
$name ]]; then
950 name_str
="${name}_file_name"
951 path_str
="${name}_file_path"
953 if [[ $
(dirname $path) == "." && ! $path =~
"." ]]; then
954 # specify a file name with out path prefix.
955 # the file path is default value init by stdio.shlib.
956 if [[ ! -e ${def_dbglogout_file_path} ]]; then
957 mkdir
-p ${def_dbglogout_file_path} 2>&1 >/dev
/null
958 if [[ $?
!= 0 ]]; then
959 # warn "can not write in \"${def_dbglogout_file_path}\", use \$USDO try again.\n"
960 sudo mkdir
-p ${def_dbglogout_file_path} 2>&1 >/dev
/null
963 declare -g ${path_str}="$def_dbglogout_file_path/$(basename $0)"
964 declare -g ${name_str}=$path
965 elif [[ -e `dirname $path` ]]; then
966 # specify a file name with valid path prefix.
968 eval $path_str=`cd $(dirname $path); pwd; cd - 2>&1 >/dev/null`
969 eval $name_str=$
(basename $path)
971 echo -ne "[failed] init_channel() failed, path of \"$path\" is not existing.\n" >&2
976 eval "mkdir -p ${!path_str} 2>/dev/null"
977 if [[ $?
!= 0 ]]; then
978 # warn "can not write in \"${!path_str}\", use \$USDO try again.\n"
979 eval sudo
"mkdir -p ${!path_str} 2>/dev/null"
981 chown
--reference ~
${!path_str} 2>/dev
/null
982 if [[ $?
!= 0 ]]; then
983 sudo chown
--reference ~
${!path_str}
985 path
=${!path_str}/${!name_str}
987 # use $logout_sfx as default surfix for logout channel, when there is no surfix specified.
988 if [[ $name == "logout" ]]; then
989 if [[ ! ${!name_str##*/} =~
"." && ! -c $path && ! -b $path ]]; then
990 eval ${name_str}="${!name_str}$logout_sfx"
991 path
="$path$logout_sfx"
993 logout_sfx
=".${path##*.}"
994 # echo ${name_str}=${!name_str}
996 # echo ${name_str}=${!name_str}
997 path
=${!path_str}/${!name_str}
1000 # use $dbgout_sfx as default surfix for dbgout channel.
1001 if [[ $name == "dbgout" && ! ${!name_str##*/} =~
"." && ! -c $path && ! -b $path ]]; then
1002 declare -g ${name_str}="${!name_str}$dbgout_sfx"
1003 path
="$path$dbgout_sfx"
1006 # if the ext-name equal to $dbgout_sfx, it is opened as a pipe file.
1007 if [[ ".${path##*.}" == "$dbgout_sfx" ]]; then
1008 [[ -f $path && ! -p $path ]] && echo -ne "[failed] init_channel() failed, non pipe file \"$path\" has been existing.\n" >&2 && return 3
1009 [[ ! -e $path ]] && mknod
-m 622 ${path} p
2>&1 > /dev
/null
1013 # others is normal file, run touch to create file.
1014 touch ${path} 2>/dev
/null
1015 [[ $?
!= 0 ]] && echo -ne "[failed] init_channel() failed, cannot open file \"$path\". check if permission allowed.\n" >&2 && return 4
1017 # open it by a idle fd value.
1018 fd
=$
(__get_file_top_valid_id
)
1019 eval "exec $fd<>$path"
1020 [[ $?
!= 0 ]] && echo -e "err: init_channel() failed, cannot open \"${!name_str}\" as a write file for channel $name." >&2 && return 5
1022 # save log file name when channel is valid.
1023 if [[ $name == "logout" ]]; then
1030 if [[ $name == "logout" ]]; then
1031 warn
"can not use pure digital number as a log filename. use the file handle instead.\n"
1032 f_logout
=$
(readlink
/proc
/self
/fd
/$path)
1037 # use directly by file handler paramter instead of file name.
1041 if [[ ! -e /proc
/self
/fd
/$path ]]; then
1042 echo -e "err: init_channel() failed, file handle \"$path\" is not opened." >&2
1045 if [[ ! -w /proc
/self
/fd
/$path ]]; then
1046 echo -e "err: init_channel() failed, file handle \"$path\" cannot be write." >&2
1050 declare -g vch_
$name="$fd"
1052 warn
"specify a valid output channel name in \"dbgout logout progstdin progstdout progstderr\" by param.\n"
1057 # fsyntax: init_dbglogout <pipe_file> <log_file> <max_lines>
1058 # fdesc: init dbgout and logout channel, init log max line limit.
1059 # specify '-' paramter to use default value.
1066 # init variable in stdio.shlib every program.
1070 # there are some different example of using:
1071 # @ cmd program, use stderr as dbgout channel, use global log path for logging.
1072 # @ deamon or app running continuously, use pipe as dbgoutchannel in global path.
1073 # and also log data in global path.
1074 # @ some times, we need to output data in current file, append ":" prefix before
1076 # @ and sometimes, there are many process of program, and we need to output data
1077 # with different file name, paaend "+" prefix.
1080 if [[ -z $pipe ||
$pipe == '-' ]]; then
1085 pipe
="$PWD/${pipe:1}"
1088 pipe
="dbgout-$$-${pipe:1}"
1093 if [[ -z $logfile ||
$logfile == '-' ]]; then
1094 logfile
=$logout_file_name
1096 case ${logfile:0:1} in
1098 logfile
="$PWD/${logfile:1}"
1101 logfile
="log-$$-${logfile:1}"
1106 if [[ -n $3 ||
$3 != '-' ]]; then
1107 max_log_lines
=$
(($3))
1109 if [[ -z $max_log_lines ]]; then
1113 init_channel dbgout
$pipe # $dbgout_file_name
1114 init_channel
logout $logfile # $logout_file_path/$logout_file_name
1117 # log_row_cnt=$(wc -l $f_logout | cut -d " " -f1)
1119 dbgset
enable dbgout
1126 dbgset
enable hilight
1135 ##############################
1136 # section: file tail
1137 ##############################