1111#
1212# NOTE about Bash Traps and Pitfalls:
1313#
14- # 1. DO NOT combine var declaration and assignment which value supplied by subshell!
14+ # 1. DO NOT combine var declaration and assignment which value supplied by subshell in ONE line !
1515# for example: readonly var1=$(echo value1)
16- # local var1 =$(echo value1)
16+ # local var2 =$(echo value1)
1717#
18- # declaration make exit code of assignment to be always 0,
18+ # Because the combination make exit code of assignment to be always 0,
1919# aka. the exit code of command in subshell is discarded.
2020# tested on bash 3.2.57/4.2.46
21+ #
22+ # solution is separation of var declaration and assignment:
23+ # var1=$(echo value1)
24+ # readonly var1
25+ # local var2
26+ # var2=$(echo value1)
2127
22- # NOTE: DO NOT declare var PROG as readonly, because its value is supplied by subshell.
28+ # NOTE: DO NOT declare var PROG as readonly in ONE line!
2329PROG=" $( basename " $0 " ) "
2430readonly PROG
2531readonly PROG_VERSION=' 2.5.0-dev'
@@ -34,7 +40,7 @@ readonly -a COMMAND_LINE=("${BASH_SOURCE[0]}" "$@")
3440# See https://www.lifewire.com/current-linux-user-whoami-command-3867579
3541# Because if run command by `sudo -u`, env var $USER is not rewritten/correct, just inherited from outside!
3642#
37- # NOTE: DO NOT declare var USER as readonly, because its value is supplied by subshell.
43+ # NOTE: DO NOT declare var USER as readonly in ONE line!
3844USER=" $( whoami) "
3945readonly USER
4046
@@ -210,9 +216,7 @@ uname | grep '^Linux' -q || die "$PROG only support Linux, not support $(uname)
210216# parse options
211217# ###############################################################################
212218
213- # NOTE: ARGS can not be declared as readonly!!
214- # readonly declaration make exit code of assignment to be always 0, aka. the exit code of `getopt` in subshell is discarded.
215- # tested on bash 4.2.46
219+ # DO NOT declare var ARGS as readonly in ONE line!
216220ARGS=$(
217221 getopt -n " $PROG " -a -o c:p:a:s:S:i:Pd:FmlhV \
218222 -l count:,pid:,append-file:,jstack-path:,store-dir:,cpu-sample-interval:,use-ps,top-delay:,force,mix-native-frames,lock-info,help,version \
@@ -363,7 +367,7 @@ readonly jstack_path
363367# biz logic
364368# ###############################################################################
365369
366- # NOTE: DO NOT declare var run_timestamp as readonly, because its value is supplied by subshell.
370+ # NOTE: DO NOT declare var run_timestamp as readonly in ONE line!
367371run_timestamp=" $( date " +%Y-%m-%d_%H:%M:%S.%N" ) "
368372readonly run_timestamp
369373readonly uuid=" ${PROG} _${run_timestamp} _${$} _${RANDOM} "
@@ -424,7 +428,7 @@ findBusyJavaThreadsByPs() {
424428
425429 # shellcheck disable=SC2206
426430 local -a ps_cmd_line=(ps $ps_process_select_options -wwLo ' pid,lwp,pcpu,user' --no-headers)
427- # DO NOT combine var ps_out declaration and assignment, because its value is supplied by subshell.
431+ # DO NOT combine var ps_out declaration and assignment in ONE line!
428432 local ps_out
429433 ps_out=" $( " ${ps_cmd_line[@]} " | sort -k3,3nr) "
430434 [ -n " $ps_out " ] || __die_when_no_java_process_found
@@ -442,7 +446,7 @@ findBusyJavaThreadsByPs() {
442446
443447# top with output field: thread id, %cpu
444448__top_threadId_cpu () {
445- # DO NOT combine var java_pid_list declaration and assignment, because its value is supplied by subshell.
449+ # DO NOT combine var java_pid_list declaration and assignment in ONE line!
446450 local java_pid_list
447451 # shellcheck disable=SC2086
448452 java_pid_list=" $( ps $ps_process_select_options -o pid --no-headers) "
@@ -465,14 +469,14 @@ __top_threadId_cpu() {
465469 # 4. top v3.3, there is 1 black line between 2 update;
466470 # but top v3.2, there is 2 blank lines between 2 update!
467471 local -a top_cmd_line=(top -H -b -d " $cpu_sample_interval " -n 2 -p " $java_pid_list " )
468- # DO NOT combine var ps_out declaration and assignment, because its value is supplied by subshell.
472+ # DO NOT combine var ps_out declaration and assignment in ONE line!
469473 local top_out
470474 top_out=$( HOME=" $tmp_store_dir " " ${top_cmd_line[@]} " )
471475 if [ -n " $store_dir " ]; then
472476 echo " $top_out " | logAndCat " ${top_cmd_line[@]} " > " ${store_file_prefix} $(( update_round_num + 1 )) _top"
473477 fi
474478
475- # DO NOT combine var result_threads_top_info declaration and assignment, because its value is supplied by subshell.
479+ # DO NOT combine var result_threads_top_info declaration and assignment in ONE line!
476480 local result_threads_top_info
477481 result_threads_top_info=$(
478482 echo " $top_out " | awk ' {
@@ -493,7 +497,7 @@ __complete_pid_user_by_ps() {
493497 # ps output field: pid, thread id(lwp), user
494498 # shellcheck disable=SC2206
495499 local -a ps_cmd_line=(ps $ps_process_select_options -wwLo ' pid,lwp,user' --no-headers)
496- # DO NOT combine var ps_out declaration and assignment, because its value is supplied by subshell.
500+ # DO NOT combine var ps_out declaration and assignment in ONE line!
497501 local ps_out
498502 ps_out=" $( " ${ps_cmd_line[@]} " ) "
499503 if [ -n " $store_dir " ]; then
0 commit comments