出力をリダイレクトしたいファイルを作成する前にコマンドを実行できますか?

出力をリダイレクトしたいファイルを作成する前にコマンドを実行できますか?

次のコマンドを実行したいと思います。

dune exec -- ocaml-print-intf file.ml

出力を次にリダイレクトします。file.mli

問題は書くことができないということです

dune exec -- ocaml-print-intf file.ml > file.mli

file.mli生成された後にdune exec -- ocaml-print-intf file.ml実行され、出力がにリダイレクトされるため、file.mliこれが問題になるのはなぜですか?署名を生成する必要があるため、file.ml最初に確認するのは署名ファイルがすでに存在するか(file.mli私たちの場合)、そうであれば出力することです。

例:

❯ dune exec -- ocaml-print-intf src/file.ml
val a : int
val b : string
❯ dune exec -- ocaml-print-intf src/file.ml > src/file.mli
❯ cat src/file.mli

❯ dune exec -- ocaml-print-intf src/file.ml

解決策が見つかりましたスポンジ

❯ dune exec -- ocaml-print-intf src/file.ml | sponge src/file.mli
❯ cat src/file.mli
val a : int
val b : string

ところで、外部ソフトウェアをインストールする必要がない別のソリューションがあるかどうか疑問に思います。

答え1

を使用すると、ksh93次のことができます。

dune exec -- ocaml-print-intf src/file.ml >; src/file.mli

>;word
出力を一時ファイルに書き込みます。コマンドが正常に完了すると名前を word に変更し、それ以外の場合は一時ファイルを削除します。 >;wordExec 組み込みでは使用できません。

sponge1行のコードでperlシミュレーションすることもできます。

dune exec -- ocaml-print-intf src/file.ml |
  perl -0777 -spe 'open STDOUT, ">", $out or die "$out: $!\n"' -- -out=src/file.mli

入力で eof が見つかると、入力sponge全体がメモリに保存され、出力ファイルにダンプされます。

では、zsh次のことができます。

mv =(dune exec -- ocaml-print-intf src/file.ml) src/file.mli

出力を=(cmd)含むように拡張される一時ファイルのパスcmd。ファイル権限が制限されることに注意してください。

答え2

次のように動作することがわかりますsponge

dune exec -- ocaml-print-intf src/file.ml | sponge src/file.mli

名前は、すべてのデータが収集された後に生成されるためですspongesrc/file.mli

sponge別の名前のファイルにリダイレクトし、データを収集して正しい名前に移動します。

dune exec -- ocaml-print-intf src/file.ml >tmpfile &&
mv tmpfile src/file.mli

tmpfileこれは中間ファイルとして使用できると仮定します。もしdune 失敗するその後、中間ファイルをクリーンアップする必要があります。これを念頭に置いて、次のことを行います。

if dune exec -- ocaml-print-intf src/file.ml >tmpfile
then
    mv tmpfile src/file.mli
else
    rm tmpfile
fi

以下を使用して一時ファイルを作成しますmktemp

tmpfile=$(mktemp)

if dune exec -- ocaml-print-intf src/file.ml >"$tmpfile"
then
    mv "$tmpfile" src/file.mli
else
    rm "$tmpfile"
fi

関連情報