stdinとstdoutでファイルを読み書きする

stdinとstdoutでファイルを読み書きする

bashで常に(ダミー)ファイルを読み書きする必要があります。途中でファイルを閉じないでください。私は読み書きするためにファイルを開き、標準入力から読み込み、読み取った内容をファイルに書き込み、ファイルから読み込み、標準出力に書き込むプログラムを探しています。一種のnetcatファイルに似ています。

問題のファイルは、応答を受け取るためにコマンドを書き込んで読み取ることができる/sys(私が作業しているジョブのカスタムファイル)にあるダミーファイルです。ここで、書き込みと後続の読み取りは同じセッションになければなりません。つまり、途中で閉じずに同じファイル記述子にあります。

Cでは簡単です。 - 、、open("file", O_RDWR)- 注:必須ではありません。write()read()seek()

標準のGNUツールがありますか、それとも書く必要がありますか?

ベストアンサー1

切り捨てなしで読み取り+書き込みモードでファイルを開くリダイレ​​クト演算子は、<>すべてのBourneに似たシェルにマッピングされていますopen(file, O_RDWR|O_CREAT)zshスローも発生しますがO_NOCTTY)またはfopen(file, "w+"))。

exec 3<> "$file"

読み取り+書き込みモードでファイルディスクリプタ3を開きます$file(存在しない場合は切り捨てないで作成します)。

しかしksh93zsh救うオペレーター。ddナビゲーションは可能ですが、後には不可能です。変数のNULバイトを除いて、どのzshシェルでもこれを使用できません。

存在する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

同じファイルを読み書きするために、ksh932つの異なる興味深いリダイレクト演算子があります。

tr 01 10 < file >; file

tr出力を一時ファイルに保存し、成功したらtr名前を次のように変更しますfile。ファイルが再生成されるため、権限と所有権が異なる場合があります。

tr -d 0 < file 1<>; file

Standard / Bourneと同じですtr -d 0 < file 1<> fileが、tr成功すると書き込みが完了した時点でfile切り捨てられます。tr入力を読み取るよりも少ない出力を生成するフィルタリングコマンド、より正確には、以前に作成されたデータを読み取らないコマンドに対してこの機能を使用できます。

zshプロセスの代替として、次のよう=(...)に使用できます。

 mv =(tr 01 10 < file) file

(効果と注意事項に似ていますksh93。)>;。または:

 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の独自のコピーを読み書きしますが、同じファイルディスクリプタを共有します。ファイル説明を開くしたがって、同じでなければなりません。

おすすめ記事