it-swarm-ja.com

スクリプト(1)の出力で、改行がCR + LF(dos-style))であるのはなぜですか?

scriptコマンドのTypeScript(つまり、保存されたファイル内)では、改行はCR + LF(\ r\n)ですが、元の行はscript)はLFです。なぜですか?それは私がまったく知らないttyの問題のようです。誰かが詳細なしでそれを説明できますか?

私は何の問題もありません。私はただ興味があります。 :)(しかし、私はそれを修正する方が良いと思います、または少なくとも文書化する必要があります。)

私のscriptはutil-linuxからのものですが、おそらくそれほど重要ではありません。

3
teika kazura

答えicarus によるコメントから学んだ後の私自身の答え:
「ファイル内の改行」と「コンソール内の改行」を区別する必要があります。コンソールでは、真の改行は、以下に示すように、直感に反してCRLFです。

UNIXの変換では、テキストファイルでLFは改行を意味し、逆もまた同様に、LFによる改行を意味します。 (「あなたが意味する」とは、自然言語のテキストで言うことを意味します。)DOS CR + LFなど。 OK。誰もがそれを知っています。

(Unix)コンソールはもっと複雑です。まず、LFとCRは制御コードであることを覚えておく必要があります。つまり、controlコンソールに使用できます。大胆に、色など。

LF(\ n、linefeed)をコンソールにフィードすると、改行が取得されます。キャッチは、まあ、twoキャッチは次のとおりです。(1)コンソールは2層になっています。それらはフィルターとレンダリング部分で構成されています。 (アドホックな命名法。)非表示の(通常のユーザーにとって)フィルターは、LFをCRLFに変換します。 (2)レンダラーは、通常の意味で改行のためにCRLF(\ r\n)を必要とします。詳細については、以下を参照してください。

script (1)コマンドによって作成されたTypeScriptファイルは、文字を記録しますafterコンソールへの入力はフィルタリングされます。 TypeScriptの改行がCRLFであるのはそのためです。

詳細&その他事実:

  • コンソールレンダラーは、LFを「カーソルを1行下に移動」として出力し、CRを「カーソルを行の先頭に移動」として出力します。
  • $ stty -opostでLF-> CRLF変換をオフにし、$ stty opostで無効にすることができます。 「opost」は「OutputPOSTprocessing」の略語です。
    • より正確には、opostが設定されている場合、onlcrはLF-> LFCRを実行します。 onocrが設定されている場合、行の先頭などでCRが削除されます。参照:POSIX第11章 " General Terminal Interface "。
  • 「Enter」キーは、UnixではLFにバインドされ、キーマップ用語では「Return」と呼ばれます。 (詳細については、 この質問 を参照してください。)
  • エスケープコードのバリエーションもあります。 man 4 console_codesは、「ESC D」(\ eD)が改行であり、「ESC E」(\ eE)が改行であることを説明しています。それらを印刷すると、±opost-nessに関係なく、「ESC D」は「カーソルを下に移動」、「ESCE」はCR + LFになります。

いくつかの実験を行うには、別のコンソールから書き込むことをお勧めします。たとえば、$ echo -ne '1st\n2nd\r\n3rd\n" > /dev/tty1は最初の非Xコンソールに書き込み、/dev/pts/0は最初のX端末です。これは最も便利な方法ではありませんが、あいまいさはほとんどありません。

2
teika kazura

プログラム出力とキャプチャされたttyストリーム(例:TypeScript)の不一致の深い理由は、ttyが以前はprintersであったことです。

UNIXの前は、テキストは常に行末にCRLFを持っていました。これは、行末の論理表現であると見なされたためではなく、文字が個別に実際の物理的意味を持っていたためです。プリントヘッドを左端まで移動します。 、そして紙を進めます。

Unixは根本的な新しいアプローチを採用しました。それは、ディスク上のテキストファイルをそれ自体で有用なオブジェクトとして扱い(プリンタの指示だけでなく)、行を論理エンティティとして扱います。 UNIXの世界観では、2文字のラインターミネータは不必要に複雑です。

しかし、彼らは既存のハードウェアで動作する必要がありました-単一の「行末」文字を認識しないプリンターとCRTダム端末で、半分の仕事をするのはCRだけで、LF to残りの半分を実行するため、変換を実行する必要があり、そのハードウェアに可能な限り最も近い場所、つまりttyドライバーで実行されました。

それ以来、すべて下位互換性があります。つまり、CRLFを要求するターミナルエミュレータと、プログラムが改行を出力するときにそれを提供するttyドライバがあります。

5
user41515