質問: シェルの制御およびリダイレクト演算子は何ですか? さまざまなコマンドをさまざまなシンボルに接続するチュートリアルをオンラインでよく見ます。例えば:command1 | command2 command1 & command2 command1 || command2 command1 && command2 他のものはコマンドをファイルに接続しているようです:command1 > file1 command1 >> file1 これは何だ?彼らは何と呼ばれている?彼らは何をしますか?それらはもっとありますか? この質問に関するメタスレッド。 。
回答: 「>」に関する警告i/oリダイレクト(<および>)について学んだばかりのunix初心者は、しばしば次のようなことを試しますコマンド ... 入力ファイル > the_same_fileまたはコマンド ...< ファイル > the_same_fileまたは、ほぼ同等に、ネコ ファイル | コマンド ...> the_same_file(grep、sed、cut、sort、spellは、このような構成で人々が使用したくなるコマンドの例です。)これらのシナリオの結果、ファイルが空になることにユーザーは驚いています。他の回答で言及されていないように見えるニュアンスは、 bash(1) のredirectionセクションの最初の文に潜んでいます: コマンドが実行される前に、シェルによって解釈される特別な表記法を使用して、その入力と出力を redirected することができます。 最初の5つの単語は、太字、斜体、下線付き、拡大、点滅、赤く着色され、 アイコン。コマンドが実行される前に、シェルが要求されたリダイレクトを実行することを強調します 。そしてまた覚えて 出力のリダイレクトにより、ファイル...が書き込み用に開かれます...。ファイルが存在しない場合は作成されます。存在する場合は、サイズがゼロに切り捨てられます。 したがって、この例では: sort roster > roster シェルは、rosterプログラムが実行を開始する前に、sortファイルを書き込み用に開き、切り捨てます(つまり、その内容をすべて破棄します)。当然、データを回復するためにできることは何もありません。 ナイーブにそれを期待するかもしれません tr "[:upper:]" "[:lower:]" < poem > poem 良いかもしれません。シェルは左から右へのリダイレクトを処理するため、読み取り(poemの標準入力の場合)のためにtrを開いてから、書き込み(標準出力の場合)のために開きます。しかし、それは役に立ちません。この一連の操作により2つのファイルハンドルが生成されますが、どちらも同じファイルを指します。シェルが読み取りのためにファイルを開いたとき、コンテンツはまだそこにありますが、プログラムが実行される前にファイルが破壊されます。 それで、それについて何をすべきか?ソリューションは次のとおりです。 実行しているプログラムに、出力先を指定する独自の内部機能があるかどうかを確認します。多くの場合、これは-o(または--output=)トークンで示されます。特に、 sort roster -o roster にほぼ等しい sort roster > roster ただし、最初のケースでは、sortプログラムが出力ファイルを開きます。そして、 after がすべての入力ファイルを読み取るまで、出力ファイルを開かないように賢くなっています。 同様に、少なくとも一部のバージョンのsedには-i(編集 私n place)出力を入力ファイルに書き戻すために使用できるオプション(ここでも、 after すべての入力が読み込まれた)。 ed/ex、emacs、pico、vi/vimなどのエディターを使用すると、ユーザーはテキストファイルを編集し、編集したテキストを元のファイルに保存できます。 edは(少なくとも)非対話的に使用できることに注意してください。 viには関連機能があります。 :%!commandと入力した場合enter、編集バッファーの内容を command に書き込み、出力を読み取り、バッファーに挿入します(元の内容を置き換えます)。 シンプルだが効果的: コマンド ... 入力ファイル > temp_file && mv temp_file 入力ファイル これには、 input_file がリンクの場合、(おそらく)別のファイルに置き換えられるという欠点があります。また、新しいファイルはデフォルトの保護であなたが所有します。特に、元の input_file がそうでなかったとしても、ファイルが最終的に誰でも読み取り可能になるというリスクがあります。 バリエーション: command ... input_file > temp_file && cp temp_file input_file && rm temp_file それでも、 temp_file は世界中で読み取り可能です。さらに良い: cp input_file temp_file && command ... temp_file > input_file && rm temp_file これらは、ファイルのリンクステータス、所有者、およびモード(保護)を保持しますが、i/oが2倍になる可能性があります。 (cpで-aや-pなどのオプションを使用して、属性を保持するように指示する必要がある場合があります。) command ... input_file > temp_file && cp --attributes-only --preserve=all input_file temp_file && mv temp_file input_file (読みやすくするために別々の行に分割)これにより、ファイルのモードは保持されます(ルートである場合は所有者)。ただし、ファイルはあなたが所有するようになります(ルートでない場合)。新しい個別のファイルにします。 このブログ (ファイルの「インプレース」編集)の提案と説明 {rm 入力ファイル && コマンド ...> 入力ファイル; } < 入力ファイル これには、 command が標準入力を処理できる必要があります(ただし、ほとんどすべてのフィルターで可能です)。ブログ自体はこれを危険なクラッジと呼んでおり、その使用を推奨していません。また、これにより、ユーザーが所有し、デフォルトの権限が付与された新しいファイル(何にもリンクされていない)も作成されます。 moreutilsパッケージには、spongeというコマンドがあります。 コマンド ... 入力ファイル |スポンジ the_same_file 詳細は this answer を参照してください。 これは私にとってまったくの驚きでした: syntaxerrorによると : [これらのソリューションのほとんど]は、読み取り専用ファイルシステムでは失敗します。「読み取り専用」とは、$home /は書き込み可能ですが、/tmpは読み取り専用(デフォルト)になります。たとえば、ubuntuを使用していて、回復コンソールを起動した場合、これは一般的なケースです。また、ヒアドキュメント演算子<<<も一時ファイルをそこに書き込むため、/tmpをread/writeにする必要があるため、そこでも機能しません。 (cf。 この質問 にはstrace ’dの出力が含まれます) その場合、以下が機能する可能性があります。 上級ユーザーのみ]コマンドが入力と同じ量の出力データを生成することが保証されている場合(例:sort、またはtr without the -dまたは-sオプション)、お試しいただけます コマンド ... 入力ファイル | dd of =the_same_file conv = notrunc 上記の説明を含む詳細、およびコマンドが同じ量を生成することが保証されている場合に機能する代替手段については、 この答え および この答え を参照してください入力があるときの出力データの数またはless (たとえば、grep、またはcut)。これらの回答には、空き容量が必要ない(または必要な容量が少ない)という利点があります。上記のcommand ... input_file > temp_file && ...形式の回答では、入力(古い)ファイル全体と出力(新しい)ファイル全体を同時に保持できる十分な空き領域がシステムに必要であることは明らかです。これは、他のほとんどのソリューション(sed -iやspongeなど)でも明らかにそうではありません。例外:sortは、出力を書き込む前にすべての入力を読み取る必要があるため、sort ... | dd ...はおそらく多くの空き領域を必要とし、一時ファイル内のすべてのデータではないにしても、ほとんどのバッファリングを行います。 上級ユーザーのみ: コマンド ... 入力ファイル 1 <> the_same_file 上記のddの回答と同じです。 n<> file構文は、指定されたファイルをファイル記述子 n に対して、切り捨てることなく、入力と出力の両方で開きます –ソートn<とn>の組み合わせ。注:一部のプログラム(catやgrepなど)は、入力と出力が同じファイルであることを検出できるため、このシナリオでは実行を拒否する場合があります。上記のディスカッションについては this answer を参照してください。また、コマンドが入力と同じ量の出力データを生成することが保証されている場合にこの回答を機能させるスクリプト以下。 警告:ピーターのスクリプトはテストしていないため、保証しません。 それで、質問は何でしたか?これはu&lで人気のトピックです。次の質問で取り上げます。 ファイルをインプレースで変更する方法はありますか? iconvで入力ファイルを変換された出力に置き換えるにはどうすればよいですか? コマンドshuf file > fileが空のファイルを残す理由 linuxで同じファイルを上書きせずに読み書きできますか? コマンドで処理されたソースファイルと同じファイルにリダイレクトします このsortコマンドで空のファイルが返されるのはなぜですか? tr stdoutをファイルにリダイレクト grep:入力ファイル「x」も出力です リダイレクト演算子はファイル記述子を並行して開きますか? リダイレクトはファイルを上書きせず、空のファイルを生成するだけです ...そして、それはスーパーユーザーやask ubuntuをカウントしていません。上記の質問に対する回答の多くの情報をこの回答に組み込みましたが、すべてではありません。 (詳細については、上記の質問とその回答をご覧ください。)追伸私は、上記で引用したブログとnoの提携を結んでいます。