From bdb7dd666072fcf8c47842ba667c4adce8127fbf Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Wed, 24 Aug 2022 09:16:05 +0900 Subject: [PATCH] edit (display-shell-version): use "ble/util/print" instead of "echo" (fixup 066ec63) --- docs/ChangeLog.md | 2 +- memo/D1779.func-source-and-lineno.sh | 100 +++++++++++++++++++++++++ memo/D1849.cd-physdir.sh | 22 ++++++ note.txt | 108 +++++++++++++++++++++++++++ src/edit.sh | 2 +- 5 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 memo/D1779.func-source-and-lineno.sh create mode 100644 memo/D1849.cd-physdir.sh diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index c1e77b08..72db7534 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -132,7 +132,7 @@ - prompt: update `PS0` between multiple commands (motivated by tycho-kirchner) `#D1560` 8f29203 - edit (`widget:display-shell-version`): include `ble.sh` version `#D1545` 750ca38 - edit (`display-shell-version`): detect configurations and print details `#D1781` 5015cb56 - - edit (`display-shell-version`): show information of the OS distribution and properly handle saved locales `#D1854` XXXXXXX + - edit (`display-shell-version`): show information of the OS distribution and properly handle saved locales `#D1854` 066ec63 XXXXXXX - complete (`ble-sabbrev`): support colored output `#D1546` 750ca38 - decode (`ble-bind`): support colored output `#D1547` 750ca38 - decode (`ble-bind`): output bindings of the specified keymaps with `ble-bind -m KEYMAP` (fixup 750ca38) `#D1559` 6e0245a diff --git a/memo/D1779.func-source-and-lineno.sh b/memo/D1779.func-source-and-lineno.sh new file mode 100644 index 00000000..d027f82c --- /dev/null +++ b/memo/D1779.func-source-and-lineno.sh @@ -0,0 +1,100 @@ +#!/bin/bash + +function ble/function#get-source-and-lineno/.extract { + local command=$1 + if [[ ${FUNCNAME[1]-} == "$_ble_util_function_util" && ${FUNCNAME[2]-} != "$_ble_util_function_util" ]]; then + return 1 + else + if [[ ${FUNCNAME[1]-} == "$_ble_util_function_name" ]]; then + local src=${BASH_SOURCE[1]} + local line=${BASH_LINENO[0]} + echo "$src:$line" >/dev/tty + if [[ -s $src ]]; then + less +"${line}g" "$src" + fi + else + declare -p BASH_SOURCE BASH_LINENO FUNCNAME >/dev/tty + fi + return 0 + fi +} 1>&11 2>&12 + +function ble/function#get-source-and-lineno { + local _ble_util_function_name=$1 + local _ble_util_function_util=$FUNCNAME + if ble/is-function "$_ble_util_function_name"; then + ( + declare -ft "$_ble_util_function_name" + builtin trap 'ble/function#get-source-and-lineno/.extract && return 0' DEBUG + "$_ble_util_function_name" + ) 11>&1 12>&2 + fi +} + +function ble/function#get-source-and-lineno.impl2 { + local ret unset_extdebug= + if ! shopt -q extdebug; then + unset_extdebug=1 + shopt -s extdebug + fi + ble/util/assign ret "declare -F '$1' &>/dev/null"; local ext=$? + if [[ $unset_extdebug ]]: then + shopt -u extdebug + fi + + if ((ext==0)); then + ret=${ret#*' '} + lineno=${ret%%' '*} + source=${ret#*' '} + fi + return "$ext" +} + +function ble/function#get-source-and-lineno.impl3 { + local ret shopt=$BASHOPTS # 古い bash で使えない + shopt -s extdebug + ble/util/assign ret "declare -F '$1' &>/dev/null"; local ext=$? + [[ :$unset_extdebug: == *:extdebug:* ]] || shopt -u extdebug + + if ((ext==0)); then + ret=${ret#*' '} + lineno=${ret%%' '*} + source=${ret#*' '} + fi + return "$ext" +} + +function ble/function#get-source-and-lineno.impl4 { + local ret ext + if ! shopt -q extdebug; then + shopt -s extdebug + ble/util/assign ret "declare -F '$1' &>/dev/null"; ext=$? + shopt -u extdebug + else + ble/util/assign ret "declare -F '$1' &>/dev/null"; ext=$? + fi + if ((ext==0)); then + ret=${ret#*' '} + lineno=${ret%%' '*} + source=${ret#*' '} + fi + return "$ext" +} + +function ble/function#get-source-and-lineno.impl2a { + local ret unset_extdebug= + shopt -q extdebug || { unset_extdebug=1; shopt -s extdebug; } + ble/util/assign ret "declare -F '$1' &>/dev/null"; local ext=$? + [[ ! $unset_extdebug ]] || shopt -u extdebug + if ((ext==0)); then + ret=${ret#*' '} + lineno=${ret%%' '*} + source=${ret#*' '} + fi + return "$ext" +} + +#ble/function#get-source-and-lineno ble/util/assign +#ble/function#get-source-and-lineno ble/function#get-source-and-lineno +#ble/function#get-source-and-lineno ble/util/is-stdin-ready +#ble/function#get-source-and-lineno ble/util/setexit diff --git a/memo/D1849.cd-physdir.sh b/memo/D1849.cd-physdir.sh new file mode 100644 index 00000000..a128bc53 --- /dev/null +++ b/memo/D1849.cd-physdir.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +mkdir -p tmp1 +cd tmp1 +touch hello.txt +(cd ..; mv tmp1 tmp2) +save_pwd1=$PWD +echo -n "1 $PWD "; pwd +ls -la + +echo "# cd -L ." +cd -L . +PWD=$save_pwd1 +echo -n "2 $PWD "; pwd + +echo "# cd $save_pwd1" +cd "$save_pwd1" +echo -n "3 $PWD "; pwd + + +cd .. +rm -rf tmp1 tmp2 diff --git a/note.txt b/note.txt index 27d23c77..01030f20 100644 --- a/note.txt +++ b/note.txt @@ -1843,6 +1843,114 @@ bash_tips - Acknowledgments - keymap の移動 (これは別 commit にする?) +2022-08-14 + + * nix develop が保存された EPOCHREALTIME を復元しようとしている + https://discourse.nixos.org/t/nix-print-dev-env-command-shows-some-assinments-to-readonly-variables/20916 + https://github.com/NixOS/nix/pull/6800 + + 一方で ble.sh は EPOCHREALTIME が勝手に別の機能に置き換えられると動作が全く + おかしくなるので (そしてはそれは他の EPOCHREALTIME を参照しているスクリプト + も同様であろう)、勝手に EPOCHREALTIME の機能を消去させられてしまっては困る。 + + * そもそも Bash では EPOCHREALTIME をそのまま上書きしても意味がない。一旦 + unset しなければならない。実際に上書きしている箇所で unset をしているのか + どうかまでは明言されていないが、報告されているエラーメッセージを観察する + 限りは unset は試みられていない。unset が最初に試みられていたのであれば、 + + bash: unset: EPOCHREALTIME: cannot unset: readonly variable + + というエラーメッセージになっていた筈である。 + + * もし unset してまで固定した時刻にしたかったのだとすれば、そして実際にそれ + をやったとしたら ble.sh の内部の時刻関連の制御が滅茶苦茶になる。場合によっ + ては固まってしまうかもしれない。 + + というかもし対話シェルで使っているなのだとしたら + + ? というかそもそも何故対話シェルの設定と print-dev-env 的なコマンド的な設定 + が混ざり合っているのだろうか。 + + % ? 会話を見ると print-dev-env は単に現在のシェル変数を出力するのに使って + % いるだけの様に見える。sed でフィルタ等するという話をしている。なので、 + % 対話シェルとして動作するとも思えない。 + % + % ? nix develop でエラーメッセージが表示されると書いている。nix develop + % を調べてみると、 nix shell + 開発用のコマンドという環境に入るらしい。 + % なので bashrc を読み込む。問題は print-dev-env が何故同じシェルで呼び + % 出されるのかという事である。特に直接 print-dev-env を自分で明示的に呼 + % び出しているのではなくて、nix develop を実行した時に自動で実行される + % のだという事を書いている。謎だ。 + % + % ? 仮に ble.sh が --lib で読み込まれるのだとしても、それを bashrc から読 + % み込むというのも変な話である。もし ble.sh の関数を個別のシェルスクリ + % プトで使いたかったとしても、それは使うシェルスクリプトの中で個別に + % source するべきなのであって、bashrc で一括して読み込むという使い方は + % 想定していない。 + % + % ? 或いは print-dev-env というのはシェル関数なのだろうか。 + + % https://github.com/NixOS/nix/blob/master/src/nix/develop.cc を見ると、 + % どうも print-dev-env と develop は内部のコードを共有しているという事の + % 様だ。つまり、develop の中で呼び出された print-dev-env が EPOCHREALTIME + % を触ってのではなくて、nix develop のコード自体が EPOCHREALTIME に触ろう + % としているのである。更に、print-dev-env も develop も単に現在の値を出力 + % しているだけであって、明示的に EPOCHREALTIME に値を設定するコードが含ま + % れているという訳では無い様な気がする。 + % + % そういう事を考えると、そもそもこの現在の値を出力するコードの時点で、 + % EPOCHREALTIME, EPOCHSECONDS, SECONDS, LINENO, BASH_LINENO, FUNCNAME, + % BASH_SOURCE, BASH_VERSION, BASH_VERSINFO, BASH_COMMAND 等の変数に値を代 + % 入しようとしているのが間違っている。 + + develop.cc のコードを確認した。先ず、print-dev-env は、実質的に nix + develop を中で呼び出してその環境における変数を出力するという様な処理を行っ + ている。そして、正にそれが目的なのだろうという気がする。 + + nix develop は何処かに .json で保存されている変数を読み取ってそれを bash + に設定しようとしている様に見える。その .json に EPOCHREALTIME が記録され + ているのは恐らく何か別の用途にも使われる事を想定しての物だろう。一方で、 + nix develop で使う時には幾ら何でも全ての変数を復元するのは変である。 + BASH_* は避けるべきだし (もしかするとこれらは既に保存する時点で除外されて + いるのかもしれない)、その他の FUNCNAME や LINENO 等も復元を試みるのは滅茶 + 苦茶である。 + + BASH_VERSINFO は bash が readonly にしていてこれに関しては警告が出ていな + いというのは BASH_* は除外しているという事なのだろうという気がする。 + + ? NixOS/nix #6800 も謎である。error ではなく warning だったと言って閉じてい + るのも謎だし、zsh では readonly だからと言って bash で動く nix develop の + 上でスキップするというのもよく分からない。 + + * 色々 develop.cc を読んだりして思った事は TLATER の 99% sure と言っている + 内容はかなり怪しいという事だ。恐らくこの TLATER は何も分かっていなくて出 + 鱈目な事を書いている。 + + 或いは実際に何処か別の箇所で EPOCHREALTIME も明示的に保存しているのだろう + か。でもコードを見る限りは ignoreVars でブラックリスト式にしているし、恐 + らく全ての変数を出力しているのだろうという気がする。 + + やはり TLATER は出鱈目を書いている。もし本当にそうなのだというのであれば + わざわざ 99% sure などと書かないし、というか 100% sure とも書かずに、断定 + で書くはずである。I'm sure なんとかとか書いている時点で勝手に推測をしてい + るのに過ぎない。 + + そもそも本当に build environment を同一にしたいのであれば、単に変数の値を + 変更したとしても意味がない。システムの時刻自体を固定しなければならないの + ではないか。そもそも最近の bash の機能である EPOCHREALTIME を参照してビル + ドを行うシステムがどれだけ存在するのかというのも謎である。そしてシステム + の時刻を固定しているのであれば、わざわざこの様な処理は必要がない筈である。 + + + →と思ったがこの json はもしかすると各 derivation の作者が手書きで用意す + る物なのだろうか。なのだとしたら EPOCHREALTIME を誤って設定している人がい + ても不思議ではないのかもしれない。然し検索してみてもその様な物は見つから + ない (とは言いつつ GitHub の検索は余り当てにならない。経験上最近検索され + たページに含まれている文字列しか検索対象になっていないような気がする)。 + + https://github.com/NixOS/nix/search?q=EPOCHREALTIME + https://github.com/NixOS/nixpkgs/search?q=EPOCHREALTIME + 2022-07-20 * konsole drag&drop diff --git a/src/edit.sh b/src/edit.sh index be4328a7..b4fcca68 100644 --- a/src/edit.sh +++ b/src/edit.sh @@ -3814,7 +3814,7 @@ function ble/widget/display-shell-version { ble/util/assign os_release '( builtin unset -v PRETTY_NAME NAME VERSION source /etc/os-release - echo "${PRETTY_NAME:-${NAME:+$NAME${VERSION:+ $VERSION}}}")' 2>/dev/null + ble/util/print "${PRETTY_NAME:-${NAME:+$NAME${VERSION:+ $VERSION}}}")' 2>/dev/null fi if [[ ! $os_release && -s /etc/release ]]; then local ret