Я часто хочу передавать относительно короткие строковые данные (хотя это может быть несколько строк) в программы командной строки, которые принимают входные данные только из файлов (например, wdiff) повторяющимся образом. Конечно, я могу создать один или несколько временных файлов, сохранить там строку и запустить команду с именем файла в качестве параметра. Но мне кажется, что эта процедура будет крайне неэффективной, если на самом деле данные будут записаны на диск, а также может нанести вред диску больше, чем необходимо, если я повторю эту процедуру много раз, например, если я хочу передать отдельные строки длинного текста файлы в wdiff. Есть ли рекомендуемый способ обойти это, скажем, с помощью псевдофайлов, таких как каналы, для временного хранения данных без фактической записи их на диск (или записи, только если они превышают критическую длину). Обратите внимание, что wdiff принимает два аргумента и,wdiff <"text"
,
98
xargs
?xargs
будет делать входные строки из файловых аргументов строки для команды. Но мне нужно наоборот.echo $data_are_here | dumb_program
?Ответы:
Используйте именованную трубу . В качестве иллюстрации:
-e
Говорит эхо , чтобы правильно интерпретировать побег новой строки (\n
). Это будет блокировать, т. Е. Ваша оболочка будет зависать, пока что-то не прочитает данные из канала.Откройте другую оболочку где-нибудь и в том же каталоге:
Вы прочтете эхо, которое освободит другую оболочку. Хотя канал существует в виде файлового узла на диске, данных, проходящих через него, нет; все это происходит в памяти. Вы можете фон (
&
) эхо.Канал имеет буфер 64 КБ (в linux) и, подобно сокету, блокирует запись при заполнении, поэтому вы не потеряете данные, если не преждевременно уничтожите программу записи.
источник
/tmp
в большинстве дистрибутивов используется для настройкиtmpfs
файловой системы, находящейся в оперативной памяти. Когда вы записываете файл в/tmp
него, он напрямую попадает в вашу оперативную память, что является хорошим ответом для полуэластичных файлов, к которым нужно быстро обращаться и много раз переписывать.В Bash вы можете использовать
command1 <( command0 )
синтаксис перенаправления, который перенаправляетcommand0
stdout и передает его вcommand1
файл с именем файла в качестве аргумента командной строки. Это называется процессом замещения .Некоторым программам, которые принимают аргументы командной строки имени файла, на самом деле нужен настоящий файл с произвольным доступом, поэтому этот метод для них не подойдет. Тем не менее, он отлично работает с
wdiff
:В фоновом режиме это создает FIFO,
<( )
передает команду внутри FIFO и передает дескриптор файла FIFO в качестве аргумента. Чтобы увидеть, что происходит, попробуйте использовать егоecho
для вывода аргумента, ничего не делая с ним:Создание именованного канала является более гибким (если вы хотите написать сложную логику перенаправления с использованием нескольких процессов), но для многих целей этого достаточно и, очевидно, проще в использовании.
Существует также
>( )
синтаксис, когда вы хотите использовать его в качестве вывода, напримерСм. Также шпаргалку перенаправления Bash для связанных методов.
источник
ssh -F <(vagrant ssh-config) default
было бы очень приятно, но увы.wdiff представляет собой особый случай из-за этого требует 2 аргумента имени файла, но и для всех команд, которые требуют только 1 аргумента и который упорно отказываются принять что-либо, кроме имени файла аргумента, есть 2 варианта:
Имя файла '-' (то есть знак минус) работает примерно в половине случаев. Кажется, это зависит от рассматриваемой команды и от того, разработчик команды перехватывает этот случай и обрабатывает его, как ожидалось. например
Существует файл psuedo с именем / dev / stdin, который существует в linux и может использоваться, если имя файла абсолютно необходимо для команды. Это с большей вероятностью сработает, поскольку не требует какой-либо специальной обработки имени файла из команды. Если fifo работает или работает метод подстановки процесса bash, то это также должно работать и не зависит от оболочки. например
источник