次のコマンドを実行したいと思います。
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 に変更し、それ以外の場合は一時ファイルを削除します。>;word
Exec 組み込みでは使用できません。
sponge
1行のコードで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
名前は、すべてのデータが収集された後に生成されるためですsponge
。src/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