最初から読むために2番目のファイルディスクリプタを使用せずにMacのbashでファイルディスクリプタを巻き戻す方法は?

最初から読むために2番目のファイルディスクリプタを使用せずにMacのbashでファイルディスクリプタを巻き戻す方法は?

環境:GNU bash、バージョン 3.2.57(1)-リリース(x86_64-apple-darwin20)

0を試してください:

exec 3<> "$(mktemp)"    # open file descriptor 3 to a temp file for read/write
echo 'foo' >&3          # write 'foo' to descriptor 3
read bar <&3            # read contents of descriptor 3 to variable named bar (not using -u 3)
echo $?                 # exit status returns "1"
exec 3>&-               # close file descriptor 3

上記のコードスニペットでは、に$bar設定することを期待していましたが、"foo"ファイル記述子3の場所がファイル記述子ファイルの末尾にあるため、機能しません。

1を試してください:

exec 3<> "$(mktemp)"    # open file descriptor 3 to a temp file for read/write
echo 'foo' >&3          # write 'foo' to descriptor 3
cat <&3                 # echo contents of of descriptor 3 to STDOUT
echo $?                 # exit status returns "0"
exec 3>&-               # close file descriptor 3

ディスクリプタ3のファイルの場所が最後にあるため、これも失敗します。

C/C++ では、次のことができます。巻き戻し(...)とfseek(...)生成されたファイル一時ファイルのファイルポインタをmktempファイルの先頭にリセットします。

既知の解決策は、以下で提供されます。ここ:(2番目の記述子を使用)

myTempFile="$(mktemp)"  # create temp file and assign to $myTempFile
exec 3> "$myTempFile"   # open file descriptor 3 for writing to $myTempFile
exec 4< "$myTempFile"   # open file descriptor 4 for reading of $myTempFile
echo 'foo' >&3          # write 'foo' to descriptor 3
read bar <&4            # read contents of descriptor 4 to variable named bar
echo $?                 # exit status returns "0"
echo "$bar"             # echo "foo"
exec 3>&-               # close file descriptor 3
exec 4>&-               # close file descriptor 4

質問™(最終):

最初から読み取るために2番目のファイル記述子を使用せずにbashでファイル記述子を巻き戻す方法は?

注:インストールしたくありません。クッシュ 93巻き戻し機能を使用してください。

exec 3<> "$(mktemp)"
echo 'foo' >&3
# Magic Happens here
read bar <&3             # expect $bar == "foo"
echo $?                  # expect "0"
exec 3>&- 

ベストアンサー1

これは興味深い問題ですが(30年間シェルで行ったことがない問題です)。間違ったツールを使用しようとした可能性があります。

Unix(UNIX、BSD、MacOS、Gnu/Linux)にはパイプがあります。パイプは、2つのファイル記述子を持つ特別なファイル(セカンダリストレージ/ディスクではありません)です。 1つは書き込み用、1つは読み取り用です。読み取り記述子は常に書き込み記述子の後に続きます。データは読み取り後に削除されます。

echo a_command | another_command

コマンドの実行時にパイプを生成できない場合があります。この場合、名前付きパイプまたはUnixソケットを使用できます。

UNIXソケットは、プロセスの1つによって作成され削除されます。これも2つの方法です。

名前付きパイプは、2つのプロセスとは独立して作成できます。

おすすめ記事