`cat <> file`はどのように機能しますか?


42

cat < fileファイルの内容を標準出力に出力します。

cat > fileCtrl+ Dが検出され、入力テキストがfileに書き込まれるまでstdinを読み取ります

cat <> file、少なくとも私のバージョンのBashでは、ファイルの内容を(エラーなしで)うまく印刷しますが、ファイルを変更したり、変更タイムスタンプを更新したりしません。

Bash規格>は、3番目のステートメントで無視されているように見えることをどのように正当化しますか?さらに重要なことは、それは何かをしいるのですか?

回答:


47

Bashは、読み取り/書き込みファイル記述子<>を作成するために使用します。

リダイレクト演算子

[n]<>word

名前がwordの展開であるファイルは、ファイル記述子nで、またはnが指定されていない場合はファイル記述子0で読み書きするために開かれます。ファイルが存在しない場合は作成されます。

cat <> filefile読み取り/書き込みを開き、記述子0(標準入力)にバインドします。< file普通に標準入力に書き込もうとする人は誰もいないでしょうが、もしできればそれはできるので、賢明に書かれたプログラムの場合と本質的に同等です。

単純なCプログラムを作成して、それを直接テストできます。標準入力を介してwrite(0, "hello", 6)書き込みます。hellofile

<>他のPOSIX準拠のシェルでも同じ効果で動作するはずです。


1
書き込み... stdinに......これに有効な使用例はありますか?
Qix 14年

3
オフハンド、私は良いものを考えることはできません。明示的な記述子(4<>file)を与えることは有用であり、0を省略した場合のデフォルトは0であると思います。stdoutからの読み取りは、これ以上はありません。
マイケルホーマー14年

5
<>また、一部のシステム(Linuxなど)では、別のプロセスが書き込み用に開くまでブロックせずに名前付きパイプを開くのに便利です。
ステファンシャゼル14年

1
@Qix:まあ、write(0、 "Password:"、10)は、ttyのようなものを要求する場合にパスワードを要求する良い方法です。私は標準エラーのみでそれを見ることに慣れていますが、特に同じテクニックが標準エラーで動作しない理由はありません。
ジョシュア14年

3
@Qix- POSIXの理論的根拠から- <>オペレーターは、複数の端末で動作し、ときどきシェルを起動したいアプリケーションを作成するのに役立ちます。そのシェルは、標準エラーから読み込んでコマンドを取得<>するページャーを使用できない限り、通常の制御端末から実行するアプリケーションを実行できませんmore。したがって、標準入力と標準出力どちらも通常の使用方法で利用できます。 cat food | more - >/dev/tty03 2<>/dev/tty03
mikeserv 14年

38

<> fileファイルを(デフォルトでは、ファイル記述子0(stdin)のように<読み取りと書き込みモードで切り捨てずに開き、事前に存在しない場合はファイル作成します

これはO_RDWR|O_CREATopen()システムコールに渡されるフラグに対応します。対照的に<is O_RDONLYおよび>is O_WRONLY|O_CREAT|O_TRUNCおよび>> O_WRONLY|O_CREAT|O_APPENDです。

アプリケーションは通常stdinに書き込みを行わないため、stdinを書き込み可能にすることはあまり有用ではありません。通常、アプリケーションは起動時に受け取るファイル記述子の読み取りおよび書き込みを想定していません。通常、stdin(または自分で開くファイル記述子)から読み取り、stdoutまたはstderr(または自分で開くファイル記述子)に書き込みます。

<> その用途を持つことができます:

  • あなたは好むかもしれcat <> fileオーバーcat < fileあなたがいる場合、コマンドは失敗したくない場合はfile存在しませんが、空がfile代わりに作成されました。
  • 切り捨てられないという側面により<>、ファイルを所定の場所に上書きするのに役立ちます。ただし、その場合、通常はファイル記述子0で使用しません。

    printf xxx 1<> file

    最初の3つのバイトを置き換えるfileとはxxx

  • Linuxなどの一部のシステムで<>は、名前付きパイプ(FIFO)でブロックせずに(他のプロセスが相手側を開くのを待たずに)名前付きパイプを開き、パイプ構造が生きたままになるようにします。例えば:

    mkfifo pipe; sed 's/foo/bar/g' <> pipe

    sed他のいくつかのプロセスからの着信データを処理しますが、決して見えませんeof


1
AT&T ksh93では、<>デフォルト1<>0<>(stdin)ではなく(stdout)であることに注意してください。これは、私が報告したPOSIX準拠のバグであり、次のリリースで修正される予定です。github.com/att/ast/issues/75ただし、現在のksh93バージョンが使用されなくなるまで、<>移植性のあるファイル記述子番号を含める必要があります。
マーティンデッカー

@MartijnDekker、私は知っている、私はそもそもそれについてあなたに言った人だった;-)。ksh93t +(動作が変更された場所)以上でのみ使用されることに注意してください。
ステファンシャゼラス

ブロックするLinux とは異なるシステム何ですか(またはそうでした)mkfifo fifo; exec 3<>fifo
ビリーおじさん
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.