diff --git a/README.md b/README.md index 99be7346..aaf9514b 100644 --- a/README.md +++ b/README.md @@ -128,8 +128,8 @@ I started working on the enhancement of the completion in August, 2018 and relea Some user configurations or other Bash frameworks may conflict with ble.sh. For example, -- `ble.sh` need to assume that common variable names and environment variables (such as `LC_*`) are not used for the global readonly variables. - In Bash, global readonly variables take effect in any scope including the local scope of the function, which means that we cannot even define a local variable that have the same name as a global variable constants. +- `ble.sh` assumes that common variable names and environment variables (such as `LC_*`) are not used for the global readonly variables. + In Bash, global readonly variables take effect in any scope including the local scope of the function, which means that we cannot even define a local variable that have the same name as a global readonly variable. This is not the problem specific to `ble.sh`, but any Bash framework may suffer from the global readonly variables. It is generally not recommended to define global readonly variables in Bash except for the security reasoning (Refs. [[1]](https://lists.gnu.org/archive/html/bug-bash/2019-03/threads.html#00150), [[2]](https://lists.gnu.org/archive/html/bug-bash/2020-04/threads.html#00200), [[3]](https://mywiki.wooledge.org/BashProgramming?highlight=%28%22readonly%22%20flag,%20or%20an%20%22integer%22%20flag,%20but%20these%20are%20mostly%20useless,%20and%20serious%20scripts%20shouldn%27t%20be%20using%20them%29#Variables)). diff --git a/ble.pp b/ble.pp index 2cc7ebad..118d9ad5 100644 --- a/ble.pp +++ b/ble.pp @@ -321,9 +321,95 @@ function ble/variable#copy-state { fi } +# BASH_XTRACEFD は書き換えると勝手に元々設定されていた fd を閉じてしまうので、 +# 元々の fd を dup しておくなど特別な配慮が必要。 +{ + _ble_bash_xtrace=() + _ble_bash_xtrace_debug_enabled= + _ble_bash_xtrace_debug_filename= + _ble_bash_xtrace_debug_fd= + _ble_bash_XTRACEFD= + _ble_bash_XTRACEFD_set= + _ble_bash_XTRACEFD_dup= +} 2>/dev/null # set -x 対策 +# From src/util.sh (ble/fd#is-open and ble/fd#alloc/.nextfd) +function ble/base/xtrace/.fdcheck { builtin : >&"$1"; } 2>/dev/null +function ble/base/xtrace/.fdnext { + (($1=${_ble_util_openat_nextfd:-30},1)) + while ble/base/xtrace/.fdcheck "${!1}"; do (($1++,1)); done +} +function ble/base/xtrace/adjust { + local level=${#_ble_bash_xtrace[@]} + if [[ $- == *x* ]]; then + _ble_bash_xtrace[level]=1 + else + _ble_bash_xtrace[level]= + fi + set +x + + ((level==0)) || return 0 + _ble_bash_xtrace_debug_enabled= + if [[ ${bleopt_debug_xtrace:-/dev/null} == /dev/null ]]; then + if [[ $_ble_bash_xtrace_debug_fd ]]; then + builtin eval "exec $_ble_bash_xtrace_debug_fd>&-" || return 0 + _ble_bash_xtrace_debug_filename= + _ble_bash_xtrace_debug_fd= + fi + else + if [[ $_ble_bash_xtrace_debug_filename != "$bleopt_debug_xtrace" ]]; then + _ble_bash_xtrace_debug_filename=$bleopt_debug_xtrace + [[ $_ble_bash_xtrace_debug_fd ]] || ble/base/xtrace/.fdnext _ble_bash_xtrace_debug_fd + builtin eval "exec $_ble_bash_xtrace_debug_fd>>\"$bleopt_debug_xtrace\"" || return 0 + fi + + _ble_bash_XTRACEFD=${BASH_XTRACEFD-} + _ble_bash_XTRACEFD_set=${BASH_XTRACEFD+set} + if [[ ${BASH_XTRACEFD-} =~ ^[0-9]+$ ]] && ble/base/xtrace/.fdcheck "$BASH_XTRACEFD"; then + ble/base/xtrace/.fdnext _ble_bash_XTRACEFD_dup + builtin eval "exec $_ble_bash_XTRACEFD_dup>&$BASH_XTRACEFD" || return 0 + builtin eval "exec $BASH_XTRACEFD>&$_ble_bash_xtrace_debug_fd" || return 0 + else + _ble_bash_XTRACEFD_dup= + local newfd; ble/base/xtrace/.fdnext newfd + builtin eval "exec $newfd>&$_ble_bash_xtrace_debug_fd" || return 0 + BASH_XTRACEFD=$newfd + fi + _ble_bash_xtrace_debug_enabled=1 + set -x + fi +} +function ble/base/xtrace/restore { + local level=$((${#_ble_bash_xtrace[@]}-1)) + ((level>=0)) || return 0 + if [[ ${_ble_bash_xtrace[level]-} ]]; then + set -x + else + set +x + fi + builtin unset -v '_ble_bash_xtrace[level]' + + ((level==0)) || return 0 + if [[ $_ble_bash_xtrace_debug_enabled ]]; then + _ble_bash_xtrace_debug_enabled= + if [[ $_ble_bash_XTRACEFD_dup ]]; then + # BASH_XTRACEFD の fd を元の出力先に繋ぎ直す + builtin eval "exec $BASH_XTRACEFD>&$_ble_bash_XTRACEFD_dup" && + builtin eval "exec $_ble_bash_XTRACEFD_dup>&-" || ((1)) + else + # BASH_XTRACEFD の fd は新しく割り当てた fd なので値上書きで閉じて良い + if [[ $_ble_bash_XTRACEFD_set ]]; then + BASH_XTRACEFD=$_ble_bash_XTRACEFD + else + builtin unset -v BASH_XTRACEFD + fi + fi + fi +} + function ble/base/.adjust-bash-options { builtin eval -- "$1=\$-" - set +exvukT -B + set +evukT -B + ble/base/xtrace/adjust [[ $2 == shopt ]] || local shopt if ((_ble_bash>=40100)); then @@ -345,12 +431,12 @@ function ble/base/.restore-bash-options { local set=${!1} shopt=${!2} [[ :$shopt: == *:nocasematch:* ]] && shopt -s nocasematch [[ :$shopt: == *:extdebug:* ]] && shopt -s extdebug + ble/base/xtrace/restore [[ $set == *B* ]] || set +B [[ $set == *T* ]] && set -T [[ $set == *k* ]] && set -k [[ $set == *u* ]] && set -u [[ $set == *v* ]] && set -v - [[ $set == *x* ]] && set -x [[ $set == *e* ]] && set -e # set -e は最後 return 0 } 2>/dev/null # set -x 対策 @@ -1476,6 +1562,8 @@ function ble-update { #%x inc.r|@|src/def| #%x inc.r|@|src/util| +bleopt/declare -v debug_xtrace '' + ble/bin/.freeze-utility-path "${_ble_init_posix_command_list[@]}" # <- this uses ble/util/assign. ble/bin/.freeze-utility-path man ble/bin/.freeze-utility-path groff nroff mandoc gzip bzcat lzcat xzcat # used by core-complete.sh diff --git a/blerc b/blerc index ae6b0ba3..38d6cf74 100644 --- a/blerc +++ b/blerc @@ -227,8 +227,8 @@ ## percentage of the CPU core usage in integer, which can be calculated by ## "(usr+sys)*100/real". The other values are all in unit of milliseconds. -#bleopt/declare -v exec_elapsed_mark $'\e[94m[ble: elapsed %s (CPU %s%%)]\e[m' -#bleopt/declare -v exec_elapsed_enabled 'usr+sys>=10000' +#bleopt exec_elapsed_mark=$'\e[94m[ble: elapsed %s (CPU %s%%)]\e[m' +#bleopt exec_elapsed_enabled='usr+sys>=10000' ## The following setting controls the exit when jobs are remaining. When an @@ -934,7 +934,15 @@ blehook/eval-after-load keymap_vi blerc/vim-load-hook ## syntax analysis information and the syntax tree. This is only effective in ## devel versions. -#bleopt_syntax_debug= +#bleopt syntax_debug= + + +## When a non-empty value is specified to this option, xtrace (set -x) is +## enabled for the internal processing of ble.sh. The value is used for the +## xtrace output log filename. [ Caution: The file size of the log file can +## soon grow up to hundred megabytes or to gigabytes. ] + +#bleopt debug_xtrace=~/blesh.xtrace ## [The setting "openat_base" needs to be set before ble.sh is loaded or diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index b6529231..bc4ff1f3 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -257,7 +257,7 @@ - complete: do not attempt an independent rhs completion for arguments (reported by rsteube) `#D1787` f8bbe2c - history: fix the unsaved history in the detached state `#D1795` 344168e - edit: fix an unexpected leave from the command layout on `read` `#D1800` 4dbf16f -- history: work around possible dirty prefix `*` in the history output `#D1808` XXXXXXX +- history: work around possible dirty prefix `*` in the history output `#D1808` 64a740d ## Documentation @@ -376,6 +376,7 @@ - make: update lint check `#D1709` 7e26dcd - test: save the test log to a file `#D1735` d8e6ea7 - benchmark: improve determination of the base time `#D1737` ad866c1 +- main: support `bleopt debug_xtrace` (requested by SuperSandro2000) `#D1810` XXXXXXX ## Contrib diff --git a/note.txt b/note.txt index b25dfad8..eeeb3d47 100644 --- a/note.txt +++ b/note.txt @@ -3238,18 +3238,6 @@ bash_tips の二層構造になっているがそれをもっと動的に変化できる様に改良するという手 も考えられる。 - * main: BASH_XTRACEFD による出力の抑制? - - | 更に set -x についてもまた駄目になっているかもしれない。→試してみた所 - | attach 部分で無駄なメッセージが沢山表示される様になっていたが実行自体には - | 問題はない様である。然し、BASH_XTRACEFD を使った方が良いのではないか。こ - | れについてはまた別の機会について考える事にする。 - - 現在の手法だと必要なエラーまで抑制してしまうし、標準エラー出力を抑制する為 - に結構無理な事をしている。BASH_XTRACEFD を使って実装した方が綺麗になるので - はないか。然し、また色々と実装上の不都合が生じるかもしれないので取り敢えず - 後でゆっくり対処する事にする。 - 2021-05-21 * progcolor: 取り敢えず builtin から始めるのが良いのではないかという気がする。 @@ -6402,6 +6390,108 @@ bash_tips Done (実装ログ) ------------------------------------------------------------------------------- +2022-06-10 + +* [棄却] 2021-05-23 main: BASH_XTRACEFD による set -x 出力の抑制? [#D1811] + + | | 更に set -x についてもまた駄目になっているかもしれない。→試してみた所 + | | attach 部分で無駄なメッセージが沢山表示される様になっていたが実行自体には問 + | | 題はない様である。然し、BASH_XTRACEFD を使った方が良いのではないか。これに + | | ついてはまた別の機会について考える事にする。 + | + | 現在の抑制の手法だと必要なエラーまで抑制してしまうし、標準エラー出力を抑制す + | る為に結構無理な事をしている。BASH_XTRACEFD を使って実装した方が綺麗になるの + | ではないか。然し、また色々と実装上の不都合が生じるかもしれないので取り敢えず + | 後でゆっくり対処する事にする。 + | + | →改めて確認してみたが、BASH_XTRACEFD は代入すると元々設定されていた fd が勝 + | 手に閉じられてしまう。 + | + | a なので元々設定されていた fd を保存する等の対処が必要になるがその為には様々 + | なコマンドを呼び出す必要がある。だとすると結局現在の位置よりも上に + | BASH_XTRACEFD の書き換えのコードを移動することはできないので、現状使ってい + | る { ... } 2>/dev/null による set -x 対策を置き換えるには至らない。 + | + | b BASH_XTRACEFD が設定されていなかった時にだけ BASH_XTRACEFD を使って set -x + | を抑制する + | + | % この様にしても BASH_XTRACEFD が既に指定されていた場合の為に { ... } + | % 2>/dev/null の対策は外す事ができない? と思ったが、既に BASH_XTRACEFD が設 + | % 定されているのだとしたら {} 2>/dev/null としても意味がない (つまり 2 に出 + | % 力される訳ではないので結局全て BASH_XTRACEFD に書き込まれてしまう)。 + | + | うーん。然し、BASH_XTRACEFD を一時的に /dev/null に設定するとしても、どの値 + | に設定するのかというのが結局問題になる。下手な fd を設定してしまうと変な所 + | に書き込まれて問題になる。自分で fd を開くにしても空いている fd を探す必要 + | がある。探す為には結局色々とコマンドを呼び出す必要がある。 + | + | 色々考えると、単に BASH_XTRACEFD に値を設定するという話ではない。元々設定され + | ている BASH_TRACEFD を待避するのにも、出力先の /dev/null を開くのにも、空いて + | いる fd を探すのにコマンドを呼び出す必要がある。という事を考えると、結局現在 + | set +x を実行している位置までは { ... } 2>/dev/null に頼る必要がある。なので、 + | 現在行っている対策を減らす効果はない。 + | + | 一方で必要なエラーまで抑制してしまっている事についてはどうか。例えば { ... } + | 2>/dev/null を単に除去してしまう。そうすれば set -x の出力も通常のエラーも全 + | て表示される様になる。然し、結局 set -x の出力を抑制する方法が他にないので、 + | やはり現在の位置までは { ... } 2>/dev/null で対策しておくしかない。 + + [結論] 当初使えるかもしれないと思ったのは BASH_XTRACEFD への設定が (設定に影 + 響を受けない) 変数代入だけで行えると考えたからであったが、その前に空いている + fd を探索して更にその fd に対して /dev/null を開く為に builtin を呼び出す必要 + がある。従って adjust-builtin-wrappers 以前は結局今までの対策を使う必要があり、 + それは現在の対策範囲と変わらない。 + +* 2022-04-15 ble.sh 内部に対する xtrace (set -x) を有効にする方法 (requested by SuperSandro2000) [#D1810] + https://github.com/akinomyoga/ble.sh/issues/186#issuecomment-1099696862 + + うーん。取り敢えず無理やり実装してしまって良い気がする。 + + * 設定 interface をどうするか + + と思ったが interface をどのようにするかが微妙である。取り敢えず提案された様 + に BLESH_DEBUG 等の環境変数経由で設定する事にするべきか。と思ったが、bleopt + で設定するべきの気がする。例えば、以下の設定がある時には set -x をしないと + いう事。 + + bleopt debug_xtrace=ファイル名 + + うーん。これに対応する為にはユーザーの設定した BASH_XTRACEFD を何処かに保存し + ておく必要がある。そしてその為にはファイルディスクリプタの探索等を実装する必 + 要がある。などなど色々考えると、ロードした瞬間に実行するには処理として複雑す + ぎる。そう思うと BASH_XTRACEFD は切り替えずにそのままユーザーが設定した物に出 + 力するというので良いのではないか。 + + * というより元々の 2021-05-23 の項目の意図は set -x の抑制を BASH_XTRACEFD を + 使ってできないかという事だった様な気がする。つまり、今回の ble.sh に対する + デバグの目的で BASH_XTRACEFD を設定するという話とは違う話なのではないか。 + + とは言いつつ set -x を抑制する為に /dev/null に設定するのを、debug_xtrace + が指定されている場合には代わりにそのファイルに BASH_XTRACEFD を設定するべき + だろう。という事を考えれば全く関係ない訳でもない。 + + 取り敢えずこちらを先に対応してから、2021-05-23 の項目に対して set -x 対策で + 強制的に抑制している範囲を減らす事ができないか検討するという事で良い気がす + る。 + + 取り敢えず簡単に作って試してみた。あっという間に数百MBに達するので実際にこれ + を使って debug する事が現実的なのかは疑問であるが、本当にクラッシュする時など + には便利かもしれない。然し、幾らか問題点がある。 + + * fixed: 元々 BASH_XTRACEFD に設定されていた fd を別の番号に dup しておく必要 + がある。何故なら BASH_XTRACEFD が変更される瞬間にその fd は閉じられてしまう + から。然しその為には空いている fd を確実に探し出す必要がある。 + + * fixed: 現在 context を switch する度にファイルを開いているが、debug_xtrace + が設定された時に fd を開いておいて以降はそれを dup するべきなのではないか。 + 毎回開き直すのは大変だし、ファイル名が相対パスで指定されていた場合、ディレ + クトリ毎にファイルが作られて面倒な事になる。 + + x 実際に試してみると set -x した時の抑制に失敗している → 何かと思ったら + adjust/restore options は入れ子で呼び出す事を許容しているのだった。対応した。 + + もっと複雑化と思ったが上記に対応したら原理的な問題ももうない気がする。 + 2022-06-09 * compat: Oh My Posh と組み合わせると動かないという質問が reddit にある (reported by abyss6166) [#D1809] diff --git a/src/util.sh b/src/util.sh index 2470bc1c..8d1aa0e7 100644 --- a/src/util.sh +++ b/src/util.sh @@ -3280,7 +3280,7 @@ fi ## @fn ble/fd#is-open fd ## 指定したファイルディスクリプタが開いているかどうか判定します。 -function ble/fd#is-open { : >&"$1"; } 2>/dev/null +function ble/fd#is-open { builtin : >&"$1"; } 2>/dev/null _ble_util_openat_nextfd= function ble/fd#alloc/.nextfd {