Чтение и запись в файл из stdin и stdout

Мне нужно постоянно читать и писать в (виртуальный) файл в bash, не закрывая файл между ними . Я ищу программу, которая откроет файл для чтения и записи, прочитает из stdin и напишет, что он читает в файле И читает из файла и записывает его в stdout. Немного похоже на netcat но на файлы.

Этот файл является виртуальным файлом в / sys (пользовательская вещь в чем-то, над чем я работаю), к которой вы пишете команду, и читает, чтобы получить ответ – где запись и последующее чтение должны выполняться в том же сеансе, т.е. в том же дескрипторе файла, не закрывая его между ними.

Легко сделать в C – open("file", O_RDWR) , write() , read() – примечание: нет необходимости seek() .

Есть ли стандартный инструмент GNU или мне нужно написать его?

2 Solutions collect form web for “Чтение и запись в файл из stdin и stdout”

Оператор перенаправления для открытия файла в режиме чтения и записи без усечения – это <> во всех оболочках типа Bourne (которые отображаются для open(file, O_RDWR|O_CREAT) (хотя zsh также выбрасывает O_NOCTTY ) или fopen(file, "w+") ):

 exec 3<> "$file" 

открывает $file в дескрипторе файла 3 в режиме чтения + записи (без его усечения и создания, если он не существует).

Однако только ksh93 и zsh ищут операторов. dd может искать, но не назад. И обратите внимание, что никакая оболочка, кроме zsh может иметь NUL байты в своих переменных.

В zsh :

 zmodload zsh/system exec 3<> $file sysread -i 3 -c 2 var # a read() of 2 bytes sysseek -u 3 0 # seek back to beginning # or sysseek -u 3 -w current -2 # to seek back 2 bytes syswrite -o 3 something-else exec 3<&- # close 

В ksh93 :

 exec 3<> "$file" var=$(dd bs=2 count=1 <&3 2>/dev/null; echo .) var=${var%?} exec 3<#((0)) # seek to beginning # or exec 3<#((CUR-2)) # to seek back 2 bytes print -ru3 something-else 

Возможно, вы все равно можете открыть файл несколько раз для каждого смещения, который вам нужен, например, здесь, чтобы читать и писать 2 байта со смещением 2 (при условии, что они не являются байтами со значением 0, если не используются zsh ):

 var=$(dd bs=2 count=1 skip=1 < "$file"; echo .) var=${var%?} printf %s something-else | dd bs=2 seek=1 1<> "$file" 

Или:

 printf %s something-else | dd bs=2 seek=1 of="$file" conv=notrunc 

Чтобы прочитать и записать в тот же файл, ksh93 имеет два других интересных оператора перенаправления:

 tr 01 10 < file >; file 

Будет хранить вывод tr во временном файле, и если tr будет успешным, переименуйте его в file (остерегайтесь, чтобы файл был создан заново, поэтому, возможно, с разными разрешениями и правами собственности).

 tr -d 0 < file 1<>; file 

То же, что и стандартный / Bourne tr -d 0 < file 1<> file за исключением того, что если tr преуспевает, file усекается, где tr закончена запись. Вы можете использовать это для команд фильтра, которые производят меньше вывода, чем они читают ввод, или, точнее, команды, которые не будут считывать данные, которые они ранее пишут.

И zsh имеет форму =(...) формы замещения процесса, которую вы можете использовать как:

  mv =(tr 01 10 < file) file 

(с аналогичным эффектом и оговорками как ksh93 's >; ). Или:

  cp =(tr 01 10 < file) file 

который сохранит атрибуты file но означает дополнительную копию.


Теперь, если вам нужно читать и писать с одинаковым смещением, используя один и тот же дескриптор файла, и ни zsh, ни ksh93 не доступны, вы всегда можете вернуться к perl / python / ruby

 perl -e ' open F, "<>", "file" or die "open: $!"; read F, $var, 1; seek F, 0, 0; print F "something-else"' 

Теперь, после повторного чтения обновленной версии вашего вопроса, похоже, что ваш файл ведет себя скорее как сокет или двунаправленный канал, а не как обычный файл для поиска.

В этом случае это может быть просто вопрос:

 socat - file:your-file 

или:

 (cat >&3 3>&- & cat <&3 3<&-) 3<> your-file 

для подачи данных из этого файла и в этот файл, как чтение из / в stdin / stdout.

Обратите внимание, что каждый cat читает / записывает в свою собственную копию дескриптора файла 3, открытого оболочкой, но они имеют одинаковое открытое описание файла, поэтому оно должно быть эквивалентным.

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

Похоже, вам действительно нужна комбинация tee и sponge . Вы можете использовать sponge из moreutils для впитывания стандартного ввода, а затем записать его в файл. Вы можете использовать tee для дублирования ввода для нескольких выходов.

Конечный результат будет выглядеть примерно так:

 command < filename | tee >(sponge filename) 

>() является примером замещения процесса . В этом случае >(sponge filename) заменяется на путь к FIFO, который идет на stdin sponge , на который пишет tee . tee также записывает свой вход в stdout самостоятельно.

Вот пример. Вы можете видеть, что вывод записывается в stdout и записывается в файл.

 $ echo 'foo bar' > file $ sed 's/foo/qux/' < file | tee >(sponge file) qux bar $ cat file qux bar 
  • выборочный stdout, stderr и ведение журнала с помощью команды script
  • Текст заменяет буквально * все * экземпляры строки через stdin, stdout
  • Предотвращать создание сценария при генерации stdout при вызове из данной программы
  • Неудачное решение от «Как перенаправить stdout и stderr в файл и отобразить stderr для консоли»
  • Tail -f передается через grep, не выводящий в файл, но выводит на консоль
  • Использование трубы STDOUT в качестве переменной?
  • Чтение stdout / stderr из подоболочки в родительский
  • Какова была первоначальная (-ые) причина (-ы) добавления «стандартной ошибки», которая отделена от «стандартного вывода»?
  • Как кодировать разные типы данных для STDOUT, чтобы STDIN мог определить, что это такое?
  • Почему задания не убиваются при выходе из системы при выполнении с помощью «> / dev / null 2> & 1 &"?
  • Перенаправить stdout программы командной строки Windows под вином
  • Interesting Posts

    Невозможно избавиться от пользователя root и привилегий

    Почему команда факторов порождает бессмыслицу по модулю RSA?

    Как я могу предотвратить запуск приложений с максимальным увеличением их окон?

    Виртуальные хосты CentOS Apache – доступная структура типов

    Как удалить все комментарии из файла, сохраняющего экранированные хэш-символы

    SSD установлен, но отображается как жесткий диск в командном выводе

    Как установить Broadcom BCM4360 на debian на Macbook pro

    Как извлечь таблицы ACPI из .ISO-файла?

    Как просмотреть изображение в tmux в iTerm2

    Как установить имя вкладки для имени псевдонима удаленного хоста, к которому я подключен?

    Изменение оболочки по умолчанию на Python

    Кто-нибудь знает верный способ установки git на Solaris 9?

    Неинтерактивная настройка и установка портов FreeBSD

    Как установить последний проигрыватель VLC в CentOS 6.4?

    Как найти все жесткие ссылки на данный файл?

    Linux и Unix - лучшая ОС в мире.