Ошибка при запуске терминала в EmacsW32
Сегодня обнаружил, что при выполнении команды M-x term в EmacsW32 возникает ошибка “apply: Spawning child process: invalid argument”. Разберемся в чем тут дело.
Функция term определена в файле C:\Program Files\Emacs\emacs\lisp\term.el. Переименуем пока на время отладки файл term.elc. Цепочка вызовов функций, приводящих к ошибке, следующая:term -> make-term -> term-exec -> term-exec-1.
Ошибка происходит в блоке (apply ‘start-process name buffer …). Функция apply применяет функцию start-process к остальным своим аргументам. Функция start-process является встроенной C-функцией emacs. На самом деле тут не одна, а две ошибки:
- Вместо “/bin/sh” нужно написать “sh”. Путь “/bin/sh” не находится. Даже если добавить в переменную окружения PATH путь C:\Cygwin файл “/bin/sh” все-равно не будет находиться.
- В блоке
(format "stty -nl echo rows %d columns %d sane 2>/dev/null;\ if [ $1 = .. ]; then shift; fi; exec \"$@\""; term-height term-width)
в переменную $1 попадает полный путь к терминальной программе. В моем случае это C:\Program Files\Emacs\emacs\bin\cmdproxy.exe. Из-за пробела в пути этот параметр воспринимается как два параметра из-за чего и возникает ошибка. Для ее устранения достаточно заключить переменную $1 в кавычки. Но чтобы кавычки корректно передались в sh их надо “заэскейпить”. Исправленный фрагмент кода выглядит следующим образом:
(apply 'start-process name buffer "sh" "-c" (format "stty -nl echo rows %d columns %d sane 2>/dev/null;\ if [ \"$1\" = .. ]; then shift; fi; exec \"$@\""; term-height term-width) "exec \"$@\"" ".." command switches)
После внесения изменений файл term.el желательно скомпилировать, а старый файл term.elc можно удалить.
Теперь можно выполнить команду M-x term и мы увидим окно программы cmdproxy:
Вуаля! Но попробуйте что-нибудь ввести в эту консоль. Что? Ничего не вводится?
На самом деле, все правильно. Так и должно быть. Терминал emacs может работать в двух режимах – char-mode (в этом режиме как раз и находится сейчас emacs) и line-mode. Переключаться между этими режимами можно с помощью сочетаний клавиш C-c C-j (line-mode) и C-c C-k (char-mode). В line-mode все нажатия клавиш дублируются на экране. То есть, line-mode – это аналог shell mode. А в char-mode все нажатия клавиш передаются непосредственно во взаимодействующий процесс. Char-mode может быть использован, например, для просмотра вывода команды top (предварительно top должна быть установлена в cygwin. top входит в пакет procps).
Но если вы перейдете в line-mode и введете команду top, то получите сообщение “top: failed tty get”. Команду top в данном случае нужно запускать с ключом -b.
А вот что означает ключ -b команды top: “Batch mode operation. Starts top in ‘Batch mode’, which could be useful for sending output from top to other programs or to a file. In this mode, top will not accept input and runs until the iterations limit you’ve set with the ‘-n’ command-line option or until killed”


osya






