Я считаю, что терминал буферизует каждую строку текста, полученного через клавиатуру, так что любая программа, имеющая файловый дескриптор (т.е. fd0) прикрепленный к терминалам файл устройства - не увидит никакого текста из строки, пока терминал не "отправит" его - что происходит при нажатии Enter.
(Как линейные редакторы оболочек обходят это - я не уверен, но они определенно попадают в текст, прежде чем вы нажмете Enter)
Кроме того, когда оболочка запускает дочерний процесс (в данном случае ping
), он переходит в состояние приостановленного/wait
ing при запуске дочернего процесса, таким образом, даже если терминал не удерживал текст от него, оболочка будет игнорировать его, предполагая, что он предназначен для дочернего процесса.
Таким образом, текст, который вы видите на экране, связан с тем, что терминал отображает его, но нет никакой программы, которая захватывает его и ничего с ним делает, пока ребенок не выйдет - и оболочка не «проснется» - затем текст не будет отправлен в редактор строк shells. Хотя я не думаю, что все терминалы обязательно это делают.
Всегда должна быть петля. Возможно, вы имеете в виду, что вам нужен инструмент, который скрывает этот цикл от вас?
Тогда вы могли бы использовать perl
's rename
(, иногда называемый prename
илиperl-rename
):
rename 's/\.[^.]+\.*\z//s'./*.*
или zsh
сzmv
:
autoload zmv
zmv '(*).[^.]##.#' '$1'
Они по умолчанию не переименовывают скрытые файлы (тех, имя которых начинается с.
). Если бы вы хотели обработать и их, вы бы сделали:
zmv '(?*).[^.]##.#(#qD)' '$1'
Те считают, что в .foo.bar.
расширение.bar.
(и не считают foo...
расширением ). Вы можете адаптироваться, если хотите считать, что это .
вместо(zmv '(?*).*(#qD)' '$1'
). Я не ожидаю, что вы захотите рассматривать это как .foo.bar.
(, который zmv '*(#qD)' '${f%%.*}'
лишит (, но потерпит неудачу, поскольку файл не может иметь пустое имя )).
Также обратите внимание, что в file.tar.gz
расширение считается .gz
, а не .tar.gz
.
Сделать это рекурсивно:
zmv '(**/)(?*).[^.]##.#(#qD)' '$1$2'
Или сrename
:
find. -depth -name '?*.*' -exec rename 's/\.[^./]+\.*\z//s' {} +
Вот подход без использования цикла.
find. -type f -name "?*.*" -exec sh -c 'mv -v "$0" "${0%.*}"' '{}' \;