出力をリダイレクトすると、時々空のファイルが生成されるのはなぜですか? [コピー]

出力をリダイレクトすると、時々空のファイルが生成されるのはなぜですか? [コピー]

シェルパイプラインはあまりにも強力で、時には残念です。

はい

同じたとえば、パイプ

echo abc > file.txt
cat file.txt | sed 's/a/1/' > file.txt

空のものをくださいfile.txt。シェルが>最初に呼び出される可能性があることに気づき、変更しました。

echo abc > file.txt
{cat file.txt | sed 's/a/1/'} > file.txt

別の空のファイルが私をまた驚かせたfile.txt。結局、効果があった醜いアプローチは次のとおりです。

echo abc > file.txt
echo $(cat file.txt | sed 's/a/1') > file.txt

これにより、シェルは最初にサブシェルを実行してからリダイレクトされます。

質問

、、...などをsed削除するより良い方法を知っていますが、ここで気になるのはシェルの構文を徹底的に学ぶことです。echocatgrepこの質問は、上記の特定の問題を解決する方法に関するものではありません。

Q1(編集者:トピック以外)文法を学ぶときに使用できる良い資料はありますか?

シェルごとに構文が異なる場合があるので心配です。

第2四半期シェルを冗長にしてコマンドを実行するたびに、シェルが何をしているのかを正確に確認できますか?

Q3(編集:トピックから抜け出す)ベストプラクティスのための他の提案はありますか?ありがとうございます!

ベストアンサー1

考える3.1.1 シェル動作、特に操作が実行される順序は次のとおりです。

  • リダイレクト処理済み今後実際にコマンドが実行されますが、
  • 拡張はリダイレクト前に処理されます。

これは、cat file > file出力リダイレクト(ファイル切り捨て)がcatビルド前に発生し、cat作業する空のファイルがあることを意味します。

しかしecho "$(cat file)" > file予想したようにコマンドの置き換えシェル拡張、これはリダイレクト前に発生します。

典型的なアドバイスは

cat file > tmpfile && mv tmpfile file

あなたはそれを使用することができますmktempここで。

または、moreutilsパッケージをインストールして使用してください。sponge

cat file | sponge file

使用している特定のコマンドを解決するには、次の変更を行います。

cat file.txt | sed 's/a/1/' > file.txt

(GNU sedと仮定)

sed -i 's/a/1/' file.txt

おすすめ記事