LINUX.ORG.RU

вопрос о перенаправлении типа «<».

 ,


0

2

вот тут

https://sites.google.com/site/vanyambauseslinux/home/vvod-i-vyvod-v-terminale

читаю

Для того, чтобы взять содержимое текстового файла в качестве ввода для команды, используется запись вида <имя_файла.

почему конструкция echo <filename не работает? Какие есть общие правила, когда это будет работать, а когда нет? Если это только для случаев типа cat < filename, то не совсем понятно зачем она вообще нужна, ведь cat filename и так работает. Каковы основные паттерны для применения этой конструкции?



Последнее исправление: linearisation (всего исправлений: 1)

почему конструкция echo <filename не работает?

Она работает.

Что echo делает со стандартным вводом?

i-rinat ★★★★★
()
while read line; do :; (echo $line | grep -o $somepattern); done < somefile.txt
cat somefile.txt | while read line; do :; (echo $line | grep -o $somepattern); done

Кому-то будет жалко памяти для вызова cat, и он предпочтет первый вариант.

anonymous
()
Ответ на: комментарий от i-rinat

выводит на стандартный вывод или ввод(хз, куда конкретно, куда-то туда)? Но это выражение ничего не выводит. Ожидается, что она в конечном итоге выведет в stdout содержимое filename, в данном случае

linearisation
() автор топика
Ответ на: комментарий от linearisation

Просто игнорирует. Проверить можно, например, так:

echo «test... test... test...» | echo

Balantay
()
Ответ на: комментарий от linearisation

Но это выражение ничего не выводит.

А какую информацию echo ожидает от пользователя (stdin) в случае, если echo запустить без перенаправления потока ввода stdin (<)?

Ответ на этот вопрос даст тебе ответ на твой.

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 1)

Еще программа получит дескриптор файла, а значит сможет более эффективно его обрабатывать, например делать seek.

shnnmnn
()

Почитай про команды-фильтры.

Если кратко, то это команды, умеющие принимать данные на стандартный поток ввода (условно, с клавиатуры) и выводить на стандартный поток вывода (монитор).

Перенаправление вида cat < filename заключается в привязывании файлового дескриптора 0 к файлу filename вместо устройства ввода.

Что это даёт?
Возьмём команду wc. Посчитаем количество строк двумя способами.

$ wc -l ./ann
35 ./ann

$ wc -l < ./ann
35

Здесь wc имеет разное поведение. В первом случае, ей был файл передан аргументом командной строки. Она взяла по нему статистику и вывела с его именем.
Во втором же случае ей был «как будто» с терминала руками подано на вход содержимое файла. Она об этом (в упращённом случае) даже не знала. Работа была аналогичной, как если бы аргументов не было (а их действительно не было) и данные были поданы на стандартный ввод (а так и было).

Конструкции вида < file, > file, cmd|cmd2 и им подобные обрабатываются на уровне шелла, запускающего твои программы. Как следствие, можно составлять цепочки, называемые «конвейерами». Но это отдельный разговор.

Возвращаясь к первому примеру.
Предположим, мы хотим посчитать количество строк в file1 и вывести в file2. Как сделать это просто с wc? Можно сделать wc -l file1 …, но тогда вывод будет содержать и имя файла, а мы хотим только количество линий. Значит, нам подойдёт в данном случае второй способ, с перенаправлением и мы сможем перенаправить вывод сразу в file2. Вот так: wc -l < file1 > file2.

Надеюсь, более-менее понятно, в чём суть.

А конкретно cat умеет принимать данные на вход потому что он тоже фильтр. И он умеет их преобразовывать. Например, есть cat -n, который выведет строки с нумерами. Можно написать какую-то команду, которая будет выдавать результат, а потом (если нам зачем-то надо) пронумеровать строки, передав это по конвейеру (... | cat -n).
Случай с cat < filename — побочный эффект того, что перенаправления парсятся оболочкой, которая это всё запускает, а значит можно и такое, хотя имеет не очень много применений.

Касательно echo — как уже сказали, оно не принимает на ввод ничего. В программу, не читающую ввода с клавиатуры бессмысленно что-то направлять. Всё что echo делает — берёт свои аргументы и выводит.


Как-то так.

evilface ★★
()
Последнее исправление: evilface (всего исправлений: 3)

почему конструкция echo <filename не работает?

Потому что echo печатает не стандартный ввод, а аргументы.

Какие есть общие правила, когда это будет работать, а когда нет?

Тогда и только тогда, когда команда умеет принимать данные со стандартного ввода (stdin).

Если это только для случаев типа cat < filename, то не совсем понятно зачем она вообще нужна

Это лишь пример.

Каковы основные паттерны для применения этой конструкции?

Есть команды, которые не умеют считывать ввод из файлов.

Иногда пишут вот так:

while read a b c; do
    ...
done < filename

intelfx ★★★★★
()

Если это только для случаев типа cat < filename, то не совсем понятно зачем она вообще нужна, ведь cat filename и так работает.

Вопрос, который вы хотите задать на самом деле звучит иначе — зачем нужно было реализовывать cat filename, когда cat < filename и так работает. Попробуйте найти на него ответ сами — он на поверхности.

Zmicier ★★★★★
()
Ответ на: комментарий от linearisation

cat <(cat<file1) <(cat<file2)

Ты ведь в курсе, как это работает?

Если нет, попробуй сделать программу, которая принимает несколько аргументов, и вызвать её так же, с <(...). Посмотри, что она получает в аргументах.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

вообще да, ты прав, она принимает имена псевдофайлов, фактически.

linearisation
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.