Проблема не в cat
и echo
, а в переменной, о которой забыли кавычки $ i
.
В сценарии оболочки, подобном Bourne (кроме zsh
), оставление переменных без кавычек вызывает операторы glob + split
для переменных.
$var
на самом деле:
glob(split($var))
Таким образом, с каждой итерацией цикла все содержимое input
(исключая завершающие символы новой строки) будет разворачиваться, разделяться, подбираться. Весь процесс требует, чтобы оболочка выделяла память, снова и снова анализируя строку. Вот почему у вас плохая работа.
Вы можете заключить переменную в кавычки, чтобы предотвратить glob + split
, но это мало вам поможет, поскольку, когда оболочке все еще нужно создать большой строковый аргумент и сканировать его содержимое на предмет echo
(Замена встроенного echo
внешним / bin / echo
даст вам слишком длинный список аргументов или нехватку памяти в зависимости от размера $ i
). Большая часть реализации echo
не совместима с POSIX, она расширяет последовательности обратной косой черты \ x
в полученных аргументах.
С cat
оболочке нужно только порождать процесс на каждой итерации цикла, а cat
будет выполнять ввод-вывод копирования. Система также может кэшировать содержимое файла, чтобы ускорить процесс cat.