Нет, проблема в том, что вы неправильно понимаете, как работают каналы.
В конвейерах Unix данные передаются слева направо (в том же направлении, что и текст на английском языке) - вывод первой программы становится вводом второй программы. Но трубы однонаправлены; выходные данные второй программы не отправляются первой программе.
Когда вы запускаете sml file.sml | echo -e "\004"
, вы не выводите Ctrl+D в sml
. Вместо этого вы отправляете вывод sml
в команду echo
где она отбрасывается, так как echo
не использует stdin.
- клавиатура →
sml file.sml
→ echo -e "\004"
→ экран
Ваша вторая попытка, sml file.sml | sleep 2 ; echo -e "\004"
, имеет аналогичную проблему - вывод sml
отправляется в sleep
(который также отбрасывает полученный вход). Однако есть еще одна проблема: команда echo
теперь вообще не является частью конвейера; Вы могли бы сказать, что |
имеет более высокий приоритет, чем ;
, (Вы можете группировать команды, используя скобки ; например, a | (b; c; d)
.)
- клавиатура →
sml file.sml
→ sleep 2
→ screen
- клавиатура →
echo -e "\004"
→ экран
Как уже говорилось выше, обе попытки написаны в неправильном направлении. Если вы хотите отправить символ \004
в sml
, конвейер должен быть записан так:
echo -e "\004" | sml file.sml
в котором sml
идет на экран, где он должен.
Однако есть еще одна проблема . Вы также путаете нажатие клавиши Ctrl D с событием "конец ввода" .
Преобразование Ctrl D в "конец ввода" происходит только на уровне оконечного устройства - другими словами, только когда вы вводите символ Ctrl+D в окно терминала. Однако, когда вы используете echo -e "\004"
в конвейере, он автоматически не переводится в "конец ввода"; вместо этого записывается фактический байт 004 [восьмеричный].
Если вы действительно хотите сказать программе, что больше нет ввода, не пишите ничего. Используйте команду, которая ничего не выводит - например, echo -n
или true
, или просто перенаправьте ввод из файла /dev/null
.
echo -n | sml file.sml
sml file.sml < /dev/null