В течение долгого времени мое понимание термина в unix-подобных системах заключалось в том, что он запускает процесс оболочки и предоставляет ему интерфейс пользователя, связываясь с ним через его stdin, stdout & stderr.
Однако недавно, глядя на проблему с запуском консольного приложения Windows через терминал Cygwin, я понимаю, что это может быть не так просто.
На http://cygwin.com/1.5/cygwin-ug-net/using-effectively.html я вижу,
Другая проблема заключается в получении выходных данных или предоставлении данных для консольных программ Windows. К сожалению, взаимодействие с консольными приложениями Windows - это не просто вопрос использования утилиты перевода. Консольные приложения Windows предназначены для запуска под command.com или cmd.exe, а некоторые не работают в других ситуациях. Cygwin может получать консольный ввод только в том случае, если он также работает в консоли (в окне DOS), поскольку Windows не предоставляет никакого способа подключения к серверной части консольного устройства. Другой традиционный метод ввода / вывода Unix, ptys (псевдо-терминалы), поддерживается Cygwin, но не полностью Windows. Основная проблема заключается в том, что Cygwin pty представляет собой канал, а некоторым приложениям Windows не нравится, когда их ввод или вывод перенаправляются на каналы.
Я написал небольшую программу на C, которую я скомпилировал под windows, используя VC++cl.exe -
#include <stdio.h>
int main(int argc, char *argv[]) {
#define BUFFER_LEN 1024
char buffer[BUFFER_LEN];
printf("echo server started\n");
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 "1\n2\n3" | /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 и запустлю эту программу как команду, она будет работать, так как тогда терминал не будет напрямую взаимодействовать с ней, а сервер SSH будет. Однако это тоже не работает -
[puneet@freestyle ~]$ ssh freestyle /cygdrive/c/echo1.exe
Hello
^ - нет ответа
Но положить это в трубу снова работает! -
[puneet@freestyle ~]$ echo -e "1\n2\n3" | ssh freestyle /cygdrive/c/echo1.exe | while read line; do echo $line; done
1
2
3
[puneet@freestyle ~]$
Может ли кто-нибудь объяснить теорию, стоящую за всеми этими наблюдениями?
Является ли взаимодействие между терминалом и оболочкой чем-то большим, чем просто использование оболочки stdin, stdout и stderr?
Чем отличается консоль Windows? Почему консольные программы Windows, кажется, работают нормально, когда находятся в конвейере с программами cygwin?