Unix/Linux EOLはLF、改行、ASCII 10、エスケープシーケンス\n
。
Python=のスニペットは、キープレスを1つだけ取得するためのものです。
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
押すと Enter このスニペットに応答して私のキーボードで、それは\r
、キャリッジリターン、ASCII 13。
Windowsの場合 Enter 送信CR LF == 13 10
。 * nixはWindowsではありません。どして Enter 10ではなく13を与える?
Thomas Dickeyの回答 はかなり正しいですが、StéphaneChazelasはDickeyの回答へのコメントで、変換が正しく設定されていないことを正しく述べています。それはライン規律の一部です。
実際、翻訳は完全にプログラム可能です。
man 3 termios manページには、基本的にすべての関連情報が含まれています。 (リンクは Linux man-pages project を参照します。これは、Linux専用の機能、およびPOSIXまたは他のシステムに共通の機能に言及しています。常にを確認してください。各ページのセクションに準拠しています。)
iflag
端末属性( Python の質問に示されているコードのold_settings[0]
)には、すべてのPOSIXyシステムで3つの関連するフラグがあります。
INLCR
:設定されている場合、入力時にNLをCRに変換しますICRNL
:設定されている場合(およびIGNCR
が設定されていない場合)、入力時にCRをNLに変換しますIGNCR
:入力時にCRを無視します同様に、関連する出力設定(old_settings[1]
)もあります。
OPOST
:出力処理を有効にします。OCRNL
:出力時にCRをNLにマップします。ONLCR
:出力でNLをCRにマップします。 (XSI。すべてのPOSIXまたは単一UNIX仕様システムでは使用できません。)ONOCR
:最初の列のCRをスキップ(出力しない)します。ONLRET
:CRをスキップ(出力しない)。たとえば、tty
モジュールに依存しないようにすることができます。 「makeraw」操作は、一連のフラグをクリアするだけです(そしてCS8
oflagを設定します)。
import sys
import termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
ch = None
try:
new_settings = termios.tcgetattr(fd)
new_settings[0] = new_settings[0] & ~termios.IGNBRK
new_settings[0] = new_settings[0] & ~termios.BRKINT
new_settings[0] = new_settings[0] & ~termios.PARMRK
new_settings[0] = new_settings[0] & ~termios.ISTRIP
new_settings[0] = new_settings[0] & ~termios.INLCR
new_settings[0] = new_settings[0] & ~termios.IGNCR
new_settings[0] = new_settings[0] & ~termios.ICRNL
new_settings[0] = new_settings[0] & ~termios.IXON
new_settings[1] = new_settings[1] & ~termios.OPOST
new_settings[2] = new_settings[2] & ~termios.CSIZE
new_settings[2] = new_settings[2] | termios.CS8
new_settings[2] = new_settings[2] & ~termios.PARENB
new_settings[3] = new_settings[3] & ~termios.ECHO
new_settings[3] = new_settings[3] & ~termios.ECHONL
new_settings[3] = new_settings[3] & ~termios.ICANON
new_settings[3] = new_settings[3] & ~termios.ISIG
new_settings[3] = new_settings[3] & ~termios.IEXTEN
termios.tcsetattr(fd, termios.TCSANOW, new_settings)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
ただし、互換性のために、これらのすべての定数がtermiosモジュールに存在するかどうかを最初に確認することもできます(非POSIXシステムで実行する場合)。 new_settings[6][termios.VMIN]
とnew_settings[6][termios.VTIME]
を使用して、保留中のデータがない場合に読み取りをブロックするかどうか、およびその時間(整数デシ秒単位)を設定することもできます。 (通常、VMIN
は0に設定され、読み取りをすぐに返す必要がある場合はVTIME
を0に設定します。または、読み取りが最大でどれだけ待機するかを正の数(1/10秒)に設定する必要があります。)
ご覧のとおり、上記(および一般に "makeraw")は、入力時のすべての変換を無効にします。これは、猫が見ている動作を説明しています。
new_settings[0] = new_settings[0] & ~termios.INLCR
new_settings[0] = new_settings[0] & ~termios.ICRNL
new_settings[0] = new_settings[0] & ~termios.IGNCR
通常の動作を得るには、これらの3行をクリアする行を省略するだけで、「未加工」の場合でも入力変換は変更されません。
new_settings[1] = new_settings[1] & ~termios.OPOST
行は、他の出力フラグの内容に関係なく、すべての出力処理を無効にします。省略して、出力処理をそのまま維持することができます。これにより、rawモードでも出力が「正常」に保たれます。 (入力が自動的にエコーされるかどうかには影響しません。これは、new_settings[3]
のECHO
cflagによって制御されます。)
最後に、新しい属性が設定されると、新しい設定のanyが設定されている場合、呼び出しは成功します。コマンドラインでパスワードを要求する場合など、設定が重要な場合は、新しい設定を取得し、重要なフラグが正しく設定/設定解除されていることを確認してください。
現在の端末設定を見たい場合は、
stty -a
通常、入力フラグは4行目にあり、出力フラグは5行目にあり、フラグが設定されていない場合は、フラグ名の前に-
が付いています。たとえば、出力は次のようになります。
speed 38400 baud; rows 58; columns 205; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
疑似端末、およびUSB TTYデバイスでは、ボーレートは無関係です。
あなたが読みたいBashスクリプトを書いた場合パスワード、次のイディオムを検討してください:
#!/bin/bash
trap 'stty sane ; stty '"$(stty -g)" EXIT
stty -echo -echonl -imaxbel -isig -icanon min 1 time 0
EXIT
トラップは、シェルが終了するたびに実行されます。 stty -g
は、スクリプトの開始時に端末の現在の設定を読み取るため、スクリプトが終了すると、現在の設定が自動的に復元されます。スクリプトを中断することもできます Ctrl+C、それは正しいことをします。 (シグナルのあるまれなケースでは、ターミナルがraw/noncanonical設定でスタックすることがあります(reset
と入力する必要があります+ + Enter ターミナルで盲目的に)、しかし実際の元の設定を復元する前にstty sane
を実行すると、毎回問題が解決しました。それがそこにある理由です。一種の追加された安全性。)
read
bashビルトインを使用して、入力行(端末に選択されていない)を読み取ることができます。または、
IFS=$'\0'
input=""
while read -N 1 c ; do
[[ "$c" == "" || "$c" == $'\n' || "$c" == $'\r' ]] && break
input="$input$c"
done
IFS
をASCII NULに設定しない場合、組み込みのread
は区切り文字を消費するため、c
は空になります。若い選手のための罠。
本質的には「手動タイプライター以来、そのように行われているから」です。本当に。
手動タイプライターにはキャリッジがあり、その上に紙が送られ、タイプ(スプリングをロードする)と同時に前進し、レバーまたはキーがありましたキャリッジが解放され、スプリングがキャリッジを左マージンに戻します。
電子データ入力(テレタイプなど)が導入されたため、彼らはそれを進めました。だから Enter 多くの端末のキーにはラベルが付けられます Return。
キャリッジを左マージンに戻した後、(手動プロセスで)ラインフィードが発生しました。繰り返しになりますが、電子デバイスは手動デバイスを模倣し、個別の line-feed 操作。
両方の操作はエンコードされているため(テレタイプをスタンドアロンデバイスよりも紙の種類を作成できるようにするため)、CR
(キャリッジリターン)とLF
(ラインフィード)があります。 ASR 33 Teletype Information からのこの画像は、右側にReturn
が付いたキーボードを示し、Line-Feed
左側にあります。 正しいにいるので、それが主なキーでした:
Unixは後で登場しました。その開発者は物事を短くすることを好みました(「[作成]の場合はcreat
も含めて、すべての略語を見てください)。おそらく2つの部分からなるプロセスに直面して、改行は、改行が先行する場合にのみ意味があると判断しました。したがって、filesから明示的な改行を削除し、端末の Return 対応する改行を送信するキー。混乱を避けるために、彼らは改行を「改行」と呼んだ。
端末でテキストを書き込む場合、Unixは逆方向に変換します。ラインフィードはキャリッジリターン/ラインフィードになります。
(つまり、「通常」:変換が行われない「ロー」モードとは対照的に、いわゆる「クックドモード」)。
概要: