Выборочный возврат списка файлов

ncне поддерживает параллельную работу с несколькими подключенными клиентами и не подходит для этой задачи. Для этой работы есть несколько подходящих инструментов, в том числе:

  1. Бернштейнtcpserver(оригинал или djbwares )или Хоффманtcpserver:
    tcpserver -v -R -H -l 0 88.109.110.161 100 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  2. моя tcpserverпрокладка:
    tcpserver -v 88.109.110.161 100 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  3. мой UCSPI -инструменты TCP:
    tcp-socket-listen 88.109.110.161 100 tcp-socket-accept --verbose sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  4. Беркоs6-tcpserver4:
    s6-tcpserver4 -v 2 88.109.110.161 100 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  5. Bercot s6 -сетевые инструменты:
    s6-tcpserver4-socketbinder 88.109.110.161 100 s6-tcpserver4d -v 2 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  6. Папеtcpsvd:
    tcpsvd -v 88.109.110.161 100 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/
  7. Сэмпсонonenetd:
    onenetd -v 88.109.110.161 100 sh -c 'exec cat 1>&2' 2>&1 |
    cyclog port100/

И можно заменить multilog, s6-log, svlogdили tinylogна cyclog.

Дополнительная литература

0
03.10.2020, 20:28
2 ответа

Вы можете сделать это довольно легко, используя массивы в bash (, который является оболочкой по умолчанию в Ubuntu, macOS использует либо bash, либо zsh для более новых версий; эти решения о bash):

  1. Выбрать все файлы (ваша исходная команда, слегка измененная):

     $ shopt -s nullglob
     $ files=(*)
     $ echo "${files[@]}"
     file.abc file.ABC file.def file.ghi file.jkl file.sh
    

    Включение опции nullglobдает пустой список, если каталог пуст. Без этой опции, если бы каталог был пуст, filesбыл бы списком из одного элемента, который является нерасширенным *.

  2. Выберите только те файлы, имена которых заканчиваются на .abc, .ABCили .def:

    .
    $ shopt -s nullglob
    $ files=(*.abc *.ABC *.def)
    $ echo "${files[@]}"
    file.abc file.ABC file.def
    
  3. Выберите все файлы, кроме тех, имена которых заканчиваются на .shили.jkl

    $ shopt -s extglob nullglob
    $ files=(!(*.sh|*.jkl))
    $ echo "${files[@]}"
    file.abc file.ABC file.def file.ghi
    
    
  4. Сопоставление без учета регистра

    $ shopt -s nocaseglob nullglob
    $ files=(*abc)
    $ echo "${files[@]}"
    file.abc file.ABC
    

Также, заметка о том, что вы делали. files="$PWD/*"не устанавливает значение $filesдля всех файлов в вашем текущем каталоге. Он устанавливает свое значение в строку, оканчивающуюся на /*:

.
$ cd /tmp/current_directory
$ files="$PWD/*" 
$ echo "$files"
/tmp/current_directory/*

Причина, по которой вы думали, что это сработало, заключалась в том, что вы использовали echo $filesбез кавычек, что означает расширение оболочки /tmp/current_directory/*. Однако если вы затем удалите файлы,та же самая команда echoбудет просто печатать /tmp/current_directory/*с $PWD, расширенным до любого каталога, в котором вы изначально запустили это. Список файлов не будет сохранен с переменной. Использование массивов, как я сделал здесь, гарантирует, что переменная хранит фактический список файлов, а не только глобус, который может быть расширен до разных значений в зависимости от того, где вы его используете.

4
18.03.2021, 23:00

Вzsh:

files=($PWD/*.(abc|ABC|DEF)(N))
print -rC1 -- $files # print raw, on one column.

(с квалификатором (N), чтобы применить nullglobк этому глобусу, чтобы $filesстал пустым списком шаблона, не соответствующего ни одному файлу, вместо сообщения об ошибке ).

Для файлов, отличных от .shи.jkl:

set -o extendedglob # needed for the ^ negation operator
files=($PWD/^*.(sh|jkl)(N))

Для сопоставления без учета регистра(.ABC/ .abc/ .Abc...):

set -o extendedglob
files=($PWD/*.(#i)abc(N))

Ваш:

FILES="$PWD/*"
echo $FILES

неверно в нескольких аспектах:

FILES="$PWD/*"не хранит список файлов в переменной $FILE. Это скалярное присваивание, которое может хранить только одно значение. Вместо этого он сохраняет в $FILESсодержимое $PWD, за которым буквально следует /*.

В, echo $FILES, так как $FILESне цитируется, в bash(, но не в zsh), расширение $FILESподлежит split+glob. И это в этот момент, и если предположить, что $FILESне содержит ни одного из символов $IFS(, которые вызовут разделение часть ), и что $PWDне содержит подстановочных знаков (. ], что также вызовет часть glob ), в которой значение расширяется до списка соответствующих файлов.

В zshsplit+glob не выполняется неявно при расширении параметра, вам нужно запросить их явно($=FILESдля разделения, $~FILESдля подстановки, $=~FILESдля обоих ).

Тогда использование echoдля вывода произвольных данных неверно, так как echoвыполняет дополнительную обработку по умолчанию (в zsh, вы можете использовать echo -E - $filesили print -r -- $files, хотя ).

3
18.03.2021, 23:00

Теги

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