Как отправить новые строки из файла на TCP-порт?

Ответ BLayer правильный, но чтобы разобрать, что здесь происходит на самом деле (, игнорируя опечатку отсутствующего -nameпервичного):

#!/bin/bash
while IFS= read -r -d '' file; do
    files+=$file
done < <(find -type f -name '*.c' -print0)
echo "${files[@]}"

В оболочке, запущенной подстановкой процесса (<(...)), следующая команда анализируется bash:

find -type f -name '*.c' -print0

Поскольку glob *.cзаключен в кавычки, bash не расширяет его . Однако одинарные кавычки удаляются. Таким образом, когда процесс findзапускается, он видит список своих аргументов:

-type
f
-name
*.c
-print0

Обратите внимание, что эти аргументы разделены нулевыми байтами , а не пробелами или символами новой строки. Это на уровне C, а не на уровне оболочки. Это связано с тем, как программы выполняются с использованием execve()в C.

Теперь для контраста в следующем фрагменте:

#!/bin/bash
find_args="-type f -name '*.c' -print0"
while IFS= read -r -d '' file; do
    files+=$file
done < <(find $find_args)
echo "${files[@]}"

Значение переменной find_argsустанавливается равным:

-type f -name '*.c' -print0

(Двойные кавычки не являются частью значения, в отличие от одинарных кавычек .)

При выполнении команды find $find_argsв соответствии с man bashтокен $find_argsподвергается расширению параметра , за которым следует разбиение на слова , за которым следует расширение имени пути (также известное как расширение шара ).

После расширения параметра у вас есть -type f -name '*.c' -print0. Обратите внимание, что это после удаления кавычки . Таким образом, одинарные кавычки не будут удалены.

После разделения слов у вас есть следующие отдельные слова:

-type
f
-name
'*.c'
-print0

Затем идет расширение имени пути. Конечно, '*.c'вряд ли будет соответствовать чему-либо, поскольку вы обычно не ставите одинарные кавычки в именах файлов, поэтому результатом будет , скорее всего, будет то, что '*.c'будет передано как литеральный шаблон в find, поэтому первичный -nameне будет работать со всеми файлами. (Успешно, только если есть файл, имя которого начинается с одинарной кавычки и заканчивается тремя символами.c')


Редактировать :Собственно, если есть такой файл,glob '*.c'будет расширяться, чтобы соответствовать этому файлу и любым другим таким файлам, а затем расширение [фактическое имя файла] будет передано в findкак шаблон . Таким образом, будет ли когда-либо достигнут -print0первичный файл или нет, зависит от (a )того, существует ли только одно такое имя файла, и (b )от того, является ли это имя файла, интерпретируемый как шар, соответствует самому себе.

Примеры:

Если вы запустите touch "'something.c'", то глобус '*.c'расширится до 'something.c', а затем первичный find-name 'something.c'также будет соответствовать этому файлу, и он будет напечатан.

Если вы запустите touch "'namewithcharset[a].c'", глобус '*.c'будет расширен до этого оболочкой, но findпервичный -name 'namewithcharset[a].c'будет не соответствовать самому себе — он будет соответствовать только 'namewithcharseta.c', которого не существует, поэтому -print0не будет достигнуто.

Если вы запустите touch "'x.c'" "'y.c'", глобус '*.c'расширится до обоих имен файлов , что приведет к выводу ошибки из find, поскольку 'y.c'не является допустимым первичным (и не может быть, так как не начинается с дефиса ).


Если установлена ​​опция nullglob, вы получите другое поведение.

См. также:

1
17.10.2019, 23:26
1 ответ

Я не знаю, какую версию netcat вы используете, но в моей нет параметра -c. Тем не менее, tail -F /var/log/changes.log | nc 127.0.0.1 1234работает для меня.

3
27.01.2020, 23:22

Теги

Похожие вопросы