Использование ресурсов с помощью конвейера, а здесь строка

Все специальные символы, как [], (), #, и т.д. необходимо записать после обратной косой черты "\". Можно попробовать, делают это:

$ touch test\[ ; ll test\[ ;
-rw-r--r-- 1 s.gvozdetskiy s.gvozdetskiy 0 Dec 12 12:00 test[
$ mkdir test\[ ; ll ./
...
drwxr-xr-x 2 s.gvozdetskiy s.gvozdetskiy     4096 Dec 12 12:04 test[
...

Я думаю поддержка hfsplus, там конкретная.

16
03.08.2015, 01:05
3 ответа

Канал - это файл, открытый в файловой системе ядра и недоступный как обычный файл на диске. Он автоматически буферизуется только до определенного размера и в конечном итоге блокируется при заполнении. В отличие от файлов, полученных на блочных устройствах, конвейеры ведут себя очень похоже на символьные устройства и поэтому обычно не поддерживают lseek () , и данные, считанные с них, не могут быть прочитаны снова, как вы могли бы сделать с обычным файлом.

Здесь-строка - это обычный файл, созданный в смонтированной файловой системе. Оболочка создает файл и сохраняет его дескриптор, немедленно удаляя его единственную ссылку на файловую систему (и, таким образом, удаляя ее) , прежде чем она когда-либо будет записывать / читать байт в / из файла. Ядро будет поддерживать пространство, необходимое для файла, до тех пор, пока все процессы не освободят для него все дескрипторы. Если ребенок, читающий из такого дескриптора, имеет возможность сделать это, его можно перемотать с помощью lseek () и прочитать снова.

В обоих случаях токены <<< и | представляют файловые дескрипторы, а не обязательно сами файлы. Вы можете лучше понять, что происходит, выполнив такие команды, как:

readlink /dev/fd/1 | cat

... или ...

ls -l <<<'' /dev/fd/*

Наиболее существенное различие между этими двумя файлами заключается в том, что здесь-строка / документ в значительной степени является делом «все сразу» - оболочка записывает в нее все данные перед тем, как предложить дескриптор чтения дочернему элементу. С другой стороны, оболочка открывает конвейер на соответствующих дескрипторах и разветвляет дочерние элементы для управления ими для конвейера - и поэтому он записывается / читается одновременно на обоих концах.

Эти различия, однако, верны только в целом . Насколько мне известно (что на самом деле не так уж и далеко) , это верно почти для каждой оболочки, которая обрабатывает сокращенную строку <<< для << перенаправление здесь-документа с единственным исключением yash . yash , busybox , dash и другие варианты ash имеют тенденцию возвращаться сюда - документы с трубками, и так в тех В конце концов, между ними действительно очень мало различий.

Хорошо, два исключения. Теперь, когда я думаю об этом, ksh93 на самом деле вообще не выполняет конвейер для | , а скорее обрабатывает весь бизнес с сокетами - хотя он и выполняет удаленные tmp для <<< * , как и большинство других. Более того, он помещает только отдельные разделы конвейера в среду подоболочки , которая является своего рода эвфемизмом POSIX для , по крайней мере, он действует как подоболочка , и поэтому даже не делать вилки.

Дело в том, что результаты теста @ PSkocik (который очень полезен) здесь могут сильно различаться по многим причинам, и большинство из них зависят от реализации. Для настройки здесь-документа наиболее важными факторами будут целевой $ {TMPDIR} тип файловой системы и текущая конфигурация / доступность кэша, а также количество записываемых данных. Для трубы это будет размер самой оболочки, потому что копии делаются для необходимых вилок. Таким образом, bash ужасен при настройке конвейера (чтобы включить $ ( команду ) подстановки) - потому что он большой и очень медленный, но с ksh93 он почти не имеет никакого значения.

Вот еще один небольшой фрагмент оболочки, демонстрирующий, как оболочка разделяет подоболочки для конвейера:

pipe_who(){ echo "$$"; sh -c 'echo "$PPID"'; }
pipe_who
pipe_who | { pipe_who | cat /dev/fd/3 -; } 3<&0

32059  #bash's pid
32059  #sh's ppid
32059  #1st subshell's $$
32111  #1st subshell sh's ppid
32059  #2cd subshell's $$
32114  #2cd subshell sh's ppid

Разница между отчетами о вызовах конвейерного pipe_who () и отчетом об одном запуске в текущей оболочке возникает из-за специфического поведения ( подоболочки ) требования pid родительской оболочки в $$ при его раскрытии. Хотя подоболочки bash определенно являются отдельными процессами, специальный параметр оболочки $$ не является надежным источником этой информации. Тем не менее, дочерняя оболочка подоболочки sh не отказывается точно сообщить свой $ PPID .

17
27.01.2020, 19:48

Ничто не заменит сравнительный анализ:

pskocik@ProBook:~ 
$ time (for((i=0;i<1000;i++)); do cat<<< foo >/dev/null; done  )

real    0m2.080s
user    0m0.738s
sys 0m1.439s
pskocik@ProBook:~ 
$ time (for((i=0;i<1000;i++)); do echo foo |cat >/dev/null; done  )

real    0m4.432s
user    0m2.095s
sys 0m3.927s
$ time (for((i=0;i<1000;i++)); do cat <(echo foo) >/dev/null; done  )
real    0m3.380s
user    0m1.121s
sys 0m3.423s

И для большего количества данных:

TENMEG=$(ruby -e 'puts "A"*(10*1024*1024)')
pskocik@ProBook:~ 
$ time (for((i=0;i<100;i++)); do echo "$TENMEG" |cat >/dev/null; done  )

real    0m42.327s
user    0m38.591s
sys 0m4.226s
pskocik@ProBook:~ 
$ time (for((i=0;i<100;i++)); do cat<<< "$TENMEG" >/dev/null; done  )

real    1m26.946s
user    1m23.116s
sys 0m3.681s
pskocik@ProBook:~ 

$ time (for((i=0;i<100;i++)); do cat <(echo "$TENMEG") >/dev/null; done  )

real    0m43.910s
user    0m40.178s
sys 0m4.119s

Похоже, конвейерная версия имеет большую стоимость установки, но в конечном итоге более эффективна.

10
27.01.2020, 19:48

Как вы уже заметили, канал создает подчиненный процесс -, а здесь строка — нет. Это может быть важно в некоторых случаях.

Сравните:

Пока:

grep $USER /etc/passwd | IFS=: read user x1 uid gid x2 home shell 
echo $user $uid $gid

ничего не отображает.

IFS=: read user x1 uid gid x2 home shell <<<$(grep $USER /etc/passwd)
echo $user $uid $gid

отображает:

myuser 1000 1000
0
29.03.2020, 09:53

Теги

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