Понимание взаимодействия терминала и оболочки

долгое время мое понимание о терминал в unix-подобных системах было то, что он запускает процесс оболочки и предоставляет пользовательский интерфейс к нему, общаясь с ним по его stdin,stdout & stderr.

однако в последнее время при рассмотрении проблемы с запуском консольного приложения windows через терминал cygwin, я понимаю, что это может быть не так просто, как это.

At http://cygwin.com/1.5/cygwin-ug-net/using-effectively.html я вижу,

другая проблема-получение выходных данных от или
консольные программы для Windows. К сожалению, взаимодействуя с
Консольные приложения Windows-это не простой вопрос использования
утилита перевода. Консольные приложения Windows предназначены для работы
под command.com или командир.exe, а некоторые не имеют дело изящно с
другие случаи. С Cygwin может получить консоль ввод только если он также
запуск в консоли (DOS box), так как Windows не предоставляет никакого способа
чтобы прикрепить к backend устройства консоли. Другой традиционный
Метод ввода/вывода Unix, ptys (псевдо-терминалы), поддерживается
Cygwin, но не полностью Windows. Основная проблема заключается в том, что Cygwin
pty труба и некоторые применения Windows не любят иметь их
ввод или вывод перенаправляется на каналы.

Я написал небольшую программу на C, который я скомпилирован под windows с использованием VC++ ' S cl.exe -

#include <stdio.h>

int main(int argc, char *argv[]) {
    #define BUFFER_LEN 1024
    char buffer[BUFFER_LEN];

    printf("echo server startedn"); 
    while (fgets(buffer, BUFFER_LEN, stdin) != NULL) {
        printf("%s", buffer);
    }

    return 0;
}

когда я запускаю терминал Cygwin (mintty.exe) и запустить эту программу, я не могу с ней взаимодействовать -

[puneet@freestyle ~]$ /cygdrive/c/echo1.exe
Hello

^-- нет ответа

но когда я положил его в трубу, он работает -

[puneet@freestyle ~]$ echo  -e "1n2n3" | /cygdrive/c/echo1.exe | while read line; do echo $line; done
1
2
3
[puneet@freestyle ~]$

в основном он не взаимодействует с mintty.exe терминал. Однако при запуске bash.exe прямо из консоли Windows, это можно корректно взаимодействовать с -

[puneet@freestyle ~]$ /cygdrive/c/echo1.exe
Hello
Hello
^Z
[puneet@freestyle ~]$

Я тогда подумал, если я ssh'd в мою машину и запустить эту программу в качестве команды, он будет работать, как тогда терминал не будет напрямую взаимодействовать с ним, но сервер SSH будет. Однако это тоже не работает -

[puneet@freestyle ~]$ ssh freestyle /cygdrive/c/echo1.exe
Hello

^-- нет ответа

но положить это в трубу снова работает ! -

[puneet@freestyle ~]$ echo  -e "1n2n3" | ssh freestyle /cygdrive/c/echo1.exe | while read line; do echo $line; done
1
2
3
[puneet@freestyle ~]$

может ли кто-нибудь объяснить теорию, стоящую за всем этим наблюдения?

это взаимодействие между терминалом и оболочкой больше, чем просто с помощью оболочки stdin,stdout и stderr?

чем отличается консоль windows? Почему консольные программы windows, кажется, работают нормально, когда в трубе с программами cygwin?

11
задан 0cd
20.01.2023 17:41 Количество просмотров материала 3434
Распечатать страницу

1 ответ

если добавить fflush(stdout) на while петли (после printf), то ваша программа будет работать, как вы ожидаете, даже внутри mintty. Вы также должны иметь возможность позвонить setbuf(stdout, NULL) в качестве первой операции вы делаете на stdout и иметь эту работу.

вы также можете запустить c:\cygwin\bin\bash внутри окна консоли windows, и ваша оригинальная программа будет работать как вы, за исключением. Я не пробовал, но вы также должны иметь возможность запускать bash внутри окна conemu или console2 и иметь свой оригинал программа работает так, как вы ожидаете.

то есть: речь идет о mintty.

вот (часть) что происходит:

консоль windows очень особенная. Windows имеет службу, называемую подсистемой времени выполнения клиент-сервер. При запуске командной строки в Windows фактически выполняется подключение к подсистеме среды выполнения клиент / сервер и it создает окно для вас.

мятный, с другой стороны, является " регулярным" окно (которое работает под управлением эмулятора терминала).

подпрограммы ввода-вывода библиотеки C от Microsoft фактически проверяют, работают ли они под окном, созданным подсистемой времени выполнения клиент/сервер, и изменяют свое поведение, если они есть. Одним из изменений, которые они делают, является отключение полной буферизации для stdout.

при запуске под mintty окна получает / помещает подпрограммы думают, что они не работают в командной строке, поэтому они делают полный буферизация.

вот еще один трюк: под bash под управлением mintty вы можете запустить cat | echo1.exe. Затем введите некоторые вещи, и когда вы нажмете ^D все буферизованные выходные данные stdout будут отображаться сразу.

причина в том, что cat | echo1.exe фишка в том, что cat - программа cygwin. Cygwin действительно, в глубине души, библиотека эмуляции posix. Так что stdin на cat эмулируется библиотекой Cygwin, а библиотека Cygwin обрабатывает ^D иначе, чем "настоящий" Windows stdin.

а если вы просто запустите echo1.exe под bash под mintty тогда ваши нажатия клавиш переходят в не эмулируемый поток файлов (т. е. ваш stdin-это настоящий Windows stdin, а не эмулируемый библиотекой Cygwin), поэтому ^D не отправлять eof. Вместо ^Z послал бы eof, но ^Z означает что-то особенное для bash, поэтому его не отправляют. Скорее вам нужно ударить ^C заявка echo1.exe немедленно (и не сбрасывает буферы, что правильно.)

2
отвечен Wandering Logic 2023-01-22 01:29

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх