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
(存在しない場合は切り捨てないで作成します)。
しかしksh93
、zsh
救うオペレーター。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
同じファイルを読み書きするために、ksh93
2つの異なる興味深いリダイレクト演算子があります。
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の独自のコピーを読み書きしますが、同じファイルディスクリプタを共有します。ファイル説明を開くしたがって、同じでなければなりません。