端末プロンプトが正しく折り返されない


171

bashで非常に長いコマンドを入力すると、ターミナルが正しく入力しているものを表示しないという問題があります。次のようなコマンドがあった場合、私は期待しています:

username@someserver ~/somepath $ ssh -i /path/to/private/key
myusername@something.someserver.com

コマンドは2行でレンダリングする必要があります。代わりに、次のように、プロンプトの周りをラップして、プロンプトの先頭から書き込みを開始することがよくあります。

myreallylongusername@something.somelongserver.comh -i /path/to/private/key

戻っていくつかの引数を変更することにした場合、カーソルがどこに表示されるかはわかりません。時にはプロンプトの途中ですが、通常は上の行にあります私が入力してるところ。

Up前のコマンドを実行すると、さらに楽しいことが起こります。私はこれをgnome-terminalとterminatorの両方とi3とCinnamonで試しました。誰かがそれが私のプロンプトだと提案したので、ここにそれがあります:

\[\033[01;32m\]\u:\[\033[01;34m\] \W\033[01;34m \$\[\033[00m\]

Ctrllreset、およびclearすべてのは、彼らが言う何が、私は後ろにコマンドを入力する場合や、Up同じことが起こります。

チェックしてcheckwinsize、bashで有効になっています。これは、80x24およびその他のウィンドウサイズで発生します。

これは私が一緒に暮らすことを学ぶものなのでしょうか?知っておくべき魔法がありますか?本当に短いプロンプトを使用するだけで解決しましたが、問題は解決しません。


1
したがって、コマンドを使用するとenv -i bash --norc修正されます。$ COLUMNSと$ LINESは一致します。それは、私の.bashrcに何か面白いことがあるということですか?
Muricula

そこで、.bashrcをコメントアウトし、プロンプトを問題のある部分、特に関連する色付け構文として分離しました。上記のPS1の何が問題になっていますか?
Muricula

1
\[\033[01;32m\]\u: \[\033[01;34m\]\W \[\033[01;34m\] \$ \[\033[0m\]行動のすごみを避けているようだ-しかし、それは完全にあなたの元プロンプトを尊重するならば...知らない

1
tput smam
serverfault

回答:


189

印刷できないシーケンスはとで囲む\[\]必要があります。PS1を見ると、の後に囲まれていないシーケンスがあります\W。ただし、2番目のエントリは冗長であり、前のステートメント"1; 34"を繰り返します。

\[\033[01;32m\]\u:\[\033[01;34m\] \W\033[01;34m \$\[\033[00m\]
                  |_____________|               |_|
                         |                       |
                         +--- Let this apply to this as well.

そのため、これには意図した色付けが必要です。

\[\033[1;32m\]\u:\[\033[1;34m\] \W \$\[\033[0m\]
                               |_____|
                                  |
                                  +---- Bold blue.

「オリジナル」を維持することでこれも機能するはずです。

\[\033[1;32m\]\u:\[\033[1;34m\] \W\[\033[1;34m\] \$\[\033[0m\]
                                  |_|         |_|
                                   |           |
                                   +-----------+-- Enclose in \[ \]

編集:

動作の理由bashは、プロンプトが実際よりも長いと考えているためです。簡単な例として、以下を使用する場合:

PS1="\033[0;34m$"
       1 2345678

プロンプトは1ではなく8文字であると考えられています。そのため、端末ウィンドウが20列の場合、12文字を入力すると20と見なされ、折り返されます。これは、バックスペースまたはを実行しようとした場合にも明らかですCtrl+u。列9で停止します。

ただし、最後の列に行がない限り、新しい行は開始されません。その結果、最初の行が上書きされます。

行を入力し続けると、32文字後に次の行に折り返されます。


あなたが持っている-または誰か-が元のシーケンスで正確に何がライン自体を繰り返したのかについての説明を持っている場合、私はそれを知ることに興味があります。これを視覚的に示した方法についても+1。

1
@illuminÉ:ソースを見ていないが、観察からの動作に関するメモを含む更新を追加しました。
ルニウム

問題が発生した場合に備えて、このWebサイトを使用して新しいものを作成できます-bashrcgenerator.com
divinedragon

@Runiumに感謝します-これを知っている方法を共有してもらえますか?これに関するいくつかのドキュメントを見つけたいです。
nycynik

2
@nycynik:観察。これに関するドキュメントに最も近いのはソースコードだと
思い

83

これは主に、ターミナルが実際のウィンドウサイズと同じではないと仮定したウィンドウのサイズに関係しています。bashを使用している場合、これを試すことができます。

$ shopt checkwinsize

取得しない場合

checkwinsize    on

次に、それをアクティブにします

$ shopt -s checkwinsize

次に、別のコマンド(などls)を実行するか、ウィンドウのサイズを1回変更するだけで、上記の方法が毎回機能します。

特にRedhatシステムの場合、問題は多くの場合、~/.bashrcを呼び出さないように誤って設定されていることが原因/etc/bashrcです。通常、bashは、デフォルトでを含む~/.bashrcを呼び出すと予想されるものをロード/etc/bashrcしますshopt -s checkwinsize


OS Xでも同じ問題があり、明らかに「ログイン」を呼び出して端末を起動すると、/ etc / bashrcを読み取る方法でbashを起動しますが、bashを直接呼び出すと〜/ .bashrcは起動しません。デフォルトで物事をソースするので、奇妙なラッピング効果が得られます。ありがとう!
rogerdpack

これも私にとってはうまくいきました。この特定のサーバーでは色が正しくなく/etc/bashrc、正しいと呼ばれていましたが、他のすべてはうまくいきました...これがラッピングの問題の原因であることが判明しました。
ダウピン


良い解決策のように見えます。しかし、私のsshセッションでは機能しません。理由はわかりません。shopt -s checkwinsizesshセッションでコマンドを実行しました。しかし、ラッピングは持続します。
強徐

これはまさに私の問題でした。ユーザー.bashrcが/ etc / bashrcを呼び出していなかったため、混乱していました。
ソブリク

9

他の回答で述べたように、などで印刷できないシーケンス\e[0;30mはでラップする必要があり\[...\]ます。

さらに(そして、私がまだ言及していないのは)、複数行のプロンプトがある場合は、その範囲外にある\r\nべきだということです。最終的にそれを理解するには、試行錯誤が必要でした。\[...\]


8

私は一度どこかで読ん(ここで、もう知らない)を使用している\001\002の代わりに\[\]、この問題を解決することができます。それは私のためにした。

ちなみに、PS1を定義することはいように見える必要はありません。

green="\001$(tput setaf 2)\002"
blue="\001$(tput setaf 4)\002"
dim="\001$(tput dim)\002"
reset="\001$(tput sgr0)\002"

PS1="$dim[\t] " # [hh:mm:ss]
PS1+="$green\u@\h" # user@host
PS1+="$blue\w\$$reset " # workingdir$

export PS1
unset green blue dim reset

2
私のPS1は、printfエスケープシーケンスがOPの問題を引き起こすコマンドを呼び出します。この解決策だけが問題を解決します。
リックミーシャム

6

これはあなたの問題のように聞こえるCOLUMNSLINES環境変数の設定。ウィンドウのサイズを変更すると、通常はgnome-terminalによって自動的に設定されます(私は信じています)resize。コマンドを発行することで、強制的に手動で設定できます。

gnome-terminalのサイズを79x17に変更すると、変数は次のように表示されます。

$ echo $COLUMNS; echo $LINES
79
17

次のように強制できます。

$ resize
COLUMNS=79;
LINES=17;
export COLUMNS LINES;

1
興味深いが、助けにはならない。
Muricula

1
これにより、コマンド "screen"を実行した後、行が正しく折り返されないという問題が修正されました。ありがとう!!
-nukeguy

5

折り返しを防ぐために、たとえば次を使用して列数を増やすこともできます。

stty columns 120

1
非常に良いアイデアではありません、それはvimを残酷に台無しにしました
phil294

3

また、ワイドユニコードシンボルを使用することでも同じ問題が発生する可能性があります(https://stackoverflow.com/a/34812608/1657819など)。ここでは、問題の原因となっスニペットは(気ある$Green$Red正しく色の文字列をエスケープされます):

FancyX='\342\234\227'
Checkmark='\342\234\223'


# Add a bright white exit status for the last command
PS1="$White\$? "
# If it was successful, print a green check mark. Otherwise, print
# a red X.
if [[ $Last_Command == 0 ]]; then
    PS1+="$Green$Checkmark "
else
    PS1+="$Red$FancyX "
fi

Bashは長さを正しく計算できないため、最も簡単な方法は、これらのワイドシンボルの3つの部分のうち2つをエスケープすることです。

FancyX='\[\342\234\]\227'
Checkmark='\[\342\234\]\223'

理にかなっています。私が推測するのは、bashは文字を数えるということです。Xは1つの文字を使用しますが、3と書き込まれるため、カウントを修正するために2つを囲む必要があります。@blauhirn答えも持つ関数で行う方法について説明します\001\002
akostadinov

FYI、これはあなたがどのようにこの形式で出力マルチバイトUnicode文字をに把握する方法である:stackoverflow.com/a/602924/520567
akostadinov
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.