On Sun, Dec 15, 2013 at 05:22:43PM +0400, Alexei V. Mezin wrote: > 15.12.2013 17:00, Alexei V. Mezin пишет: > [alexei@bigbear ncurses-5.9]$ echo $LINES $COLUMNS > 56 154 > > Я так понял, что bash выставляет эти переменные самостоятельно. А из man > resizeterm > > If the environment variables LINES or COLUMNS are set, this overrides > the library's use of the window size obtained from the operating > system. Thus, even if a SIGWINCH is received, no screen size change may > be recorded. > > То есть пока bash будет выставлять такие переменные, htop нормально > работать не будет. Или перед запуском надо делать unset. > > Значит это не баг, а просто htop и подобные плохо написаны, надо > переделывать на использование сигналов напрямую. На самом деле, возможно, это баг в bash (точнее, во взаимодействии bash с внешней библиотекой libreadline). Дело в том, что в libreadline есть функция sh_set_lines_and_columns(), которая как раз и добавляет в окружение текущего процесса переменные LINES и COLUMNS: http://git.altlinux.org/gears/r/readline.git?p=readline.git;a=blob;f=readline/shell.c;h=346f8113d43d742191f34f431d55e94316e4431d;hb=bc8ee94c5760cc286148d7ab25f2606c0eeeb52a#l121 Однако ближе к началу файла shell.c есть следующий комментарий: 88 /* All of these functions are resolved from bash if we are linking readline 89 as part of bash. */ http://git.altlinux.org/gears/r/readline.git?p=readline.git;a=blob;f=readline/shell.c;h=346f8113d43d742191f34f431d55e94316e4431d;hb=bc8ee94c5760cc286148d7ab25f2606c0eeeb52a#l88 И действительно, в самом bash тоже определяется функция sh_set_lines_and_columns(): http://git.altlinux.org/gears/b/bash.git?p=bash.git;a=blob;f=bash/variables.c;h=1c782534e22d77e492cb66cad6d8666c9a911e23;hb=ab284e13150cb2edf3345256c6ddd919babf3a24#l864 В отличие от реализации в libreadline, функция из bash использует не setenv(), а внутреннюю функцию bash bind_variable(), которая устанавливает внутреннюю переменную shell, по умолчанию не экспортирующуюся в дочерние процессы; именно такое поведение можно наблюдать сейчас в zsh - в скриптах можно использовать переменные $LINES и $COLUMNS, но zsh не передаёт эти переменные другим процессам, если не выполнить export явно. Однако в ALT пакеты bash и libreadline собраны таким образом, что при вызове sh_set_lines_and_columns() из функций libreadline всегда вызывается реализация этой функции внутри libreadline - перекрытие её реализацией из bash, предполагавшееся разработчиками, не выполняется. $ gdb bash GNU gdb (GDB) 7.5.0.20121002-alt3 (ALT Linux) Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-alt-linux". For bug reporting instructions, please see: ... Reading symbols from /bin/bash...Reading symbols from /usr/lib/debug/bin/bash.debug...done. done. (gdb) b sh_set_lines_and_columns Breakpoint 1 at 0x42bee0: file ../variables.c, line 869. (gdb) r Starting program: /bin/bash Breakpoint 1, sh_set_lines_and_columns (lines=40, cols=80) at ../variables.c:869 869 { (gdb) bt #0 sh_set_lines_and_columns (lines=40, cols=80) at ../variables.c:869 #1 0x000000000046a395 in get_new_window_size (from_sig=from_sig@entry=0, rp=rp@entry=0x0, cp=cp@entry=0x0) at ../../../lib/sh/winsize.c:75 #2 0x00000000004331fb in get_tty_state () at ../jobs.c:1968 #3 get_tty_state () at ../jobs.c:1938 #4 0x000000000043380d in initialize_job_control (force=force@entry=0) at ../jobs.c:3598 #5 0x00000000004166c6 in shell_initialize () at ../shell.c:1673 #6 0x0000000000414c33 in main (argc=1, argv=0x7fffffffe4c8, env=0x7fffffffe4d8) at ../shell.c:543 (gdb) c Continuing. Breakpoint 1, sh_set_lines_and_columns (lines=40, cols=80) at ../shell.c:126 126 ../shell.c: Нет такого файла или каталога. (gdb) bt #0 sh_set_lines_and_columns (lines=40, cols=80) at ../shell.c:126 #1 0x00007ffff7bc1d2d in _rl_get_screen_size (tty=, ignore_env=0) at ../terminal.c:299 #2 0x00007ffff7bc23ca in _rl_init_terminal_io (terminal_name=) at ../terminal.c:521 #3 0x00007ffff7bc253b in _rl_set_screen_size (rows=40, cols=) at ../terminal.c:312 #4 0x000000000046a3a3 in get_new_window_size (from_sig=from_sig@entry=0, rp=rp@entry=0x0, cp=cp@entry=0x0) at ../../../lib/sh/winsize.c:77 #5 0x00000000004331fb in get_tty_state () at ../jobs.c:1968 #6 get_tty_state () at ../jobs.c:1938 #7 0x000000000043380d in initialize_job_control (force=force@entry=0) at ../jobs.c:3598 #8 0x00000000004166c6 in shell_initialize () at ../shell.c:1673 #9 0x0000000000414c33 in main (argc=1, argv=0x7fffffffe4c8, env=0x7fffffffe4d8) at ../shell.c:543 Видно, что во втором по порядку вызове, сделанном изнутри libreadline, была вызвана именно реализация из libreadline, а не из bash (имена файлов отличаются). Кстати, аналогичная проблема наблюдается и в самом gdb, который тоже использует libreadline: https://lists.gnu.org/archive/html/bug-readline/2013-09/msg00004.html В некоторых других дистрибутивах как минимум bash ведёт себя правильнее (не экспортирует переменные LINES и COLUMNS): http://lists.gnu.org/archive/html/bug-bash/2013-07/msg00056.html http://lists.gnu.org/archive/html/bug-bash/2013-07/msg00063.html