次の行に折り返すために長いコマンド行を取得するにはどうすればよいですか?


108

Ubuntuで長い間気づいていたことは、新しい行に折り返すのではなく、端末の幅よりも長い(幅の広い)コマンドラインでコマンドを入力しているときです同じ行の1列目で、コマンドラインの先頭の上書きを開始します。(実際のコマンドは実際には上書きされませんが、視覚的には、表示されたテキストが上書きされます)。

見ずに説明するのは難しいですが、端末の幅が20文字(私の場合は120文字に近い-例のため)で、英語のアルファベットをエコーし​​たいとします。私が入力するのはこれです:

echo abcdefghijklmnopqrstuvwxyz

しかし、キーを押す前の私の端末は次のようになっています。

pqrstuvwxyzghijklmno

Enterキーを押すと、エコーします

abcdefghijklmnopqrstuvwxyz

そのため、コマンドが正しく受信されたことがわかります。「o」の後にタイピングをラップし、同じ行で最初からやり直しました。

幅が20文字しかない端末でこのコマンドを入力すると、次のようになります。

echo abcdefghijklmno
pqrstuvwxyz

背景:私はシェルとしてbashを使用しており、〜/ .bashrcに次の行があります。

set -o vi

VIコマンドを使用してコマンドラインをナビゲートできるようにします。現在、Ubuntu 10.10サーバーを使用しており、Puttyでサーバーに接続しています。

私が働いていた他の環境では、長いコマンドラインを入力すると、コマンドが端末の幅より長くなり、入力し続けると、作業中の行の下に新しい行が追加され、コマンドが表示されます2つの異なる行。しかし、Ubuntuの使用を覚えている限り、私の長いコマンドは1行しか占有しません。

これは、履歴内の前のコマンドに戻るときにも発生します(Escを押してから「K」を押して前のコマンドに戻る)-端末幅より長い前のコマンドに到達すると、コマンドラインが取得されますマングルされ、コマンドのどこにいるのかわかりません。

長いコマンド全体が表示されることがわかった唯一の回避策は、「Esc-V」を押すことです。これにより、VIエディターで現在のコマンドが開きます。

.bashrcファイルに奇妙なものはないと思います。「set -o vi」行をコメントアウトしましたが、まだ問題がありました。

Puttyの新しいコピーをダウンロードし、構成に変更を加えませんでした。接続するためにホスト名を入力しただけで、まだ問題があります。構成を変更します)

他の誰かがこの問題を抱えていて、誰もそれを修正する方法を考えることができますか?

編集

それは私の.bashrcファイルでした。同じプロファイルをマシンからマシンにコピーし、$ PS1で特殊文字を使用して、何らかの形でそれをスローしました。私は今、私の$ PS1の標準bash変数に固執しています。

.bashrcのヒントを提供してくれた@ændrükに感謝します!

...編集の終了...


1
問題の原因が.bashrcファイルではないことを確認するために、一時的にのコピーで置き換えることをお勧めします/etc/skel/.bashrc。変更を有効にするには再接続する必要があり、独自の.bashrcのバックアップを必ず保持してください。
アーンドリューク

1
どの端末アプリケーションを使用していますか?あなたが説明している動作は普通ではなく、デフォルトではありません。
ジョアンピント

私が働いたシェル(およびCisco CLI)では、Ctrl-Lを入力して、入力している行が画面外であっても再表示できます。あなたの状況では、それはあなたが話している壊れた出力をまだ生成するかもしれませんが、私は興味があります。
ベラク

3
ソリューションを説明する「回答」を作成し、承認済みとしてマークしてください。それは少しばかげているように思えるかもしれませんが、適切な回答があれば、サイトを整理しやすくなり、将来同様の問題を抱えている他の人をより効果的に導くことができます。
アーンドリューク

tput smam
serverfault

回答:


136

PS1のすべての印刷不可バイトがに含まれていることを確認してください\[ \]。それ以外の場合、bashはプロンプトの長さでそれらをカウントします。プロンプトの長さを使用して、行をいつ折り返すかを決定します。

たとえば、ここでbashはプロンプトを19列幅としてカウントしますが、端末によって表示されるプロンプトは10列幅のみです(My promptシアンで>書かれ、デフォルトの色で書かれています):

PS1='\e[36mMy prompt\e[0m>'         # bash count: 19, actual: 10

ここでは、特別なエスケープ\[\]エスケープの間のバイトを無視するため、プロンプトは10列幅としてのみカウントされます。

PS1='\[\e[36m\]My prompt\[\e[0m\]>' # bash count: 10, actual: 10

ただし、良い練習のためにtput、ハードコーディングではなく、ターミナルエスケープの生成に使用します。

cyan=$(tput setaf 6) # \e[36m
reset=$(tput sgr0)   # \e[0m
PS1='\[$cyan\]My prompt\[$reset\]>'

の詳細については、http://mywiki.wooledge.org/BashFAQ/053、およびhttp://wiki.bash-hackers.org/scripting/terminalcodesを参照してくださいtput


3
これは、受け入れられた答えでは得られない問題の素晴らしい説明です
ジェイミークック

コードの最後の行でPS1='...'単一引用符を防ぐことはできません。理由:$cyan$reset置換から?
-andrybak

2
@andrybak、彼らは予防やる$cyan$reset置換されることから、しかしPS1、プロンプトが印刷されるたびに評価されます。これを試してみるPS1='$var> 'と、varさまざまな値を指定して、プロンプトがどのように変化するかを確認できます。次にPS1="$var> " 、プロンプトが静的なままであることを確認してください。$var割り当て中に拡張され、毎回PS1評価されるわけではありません。
ガイラ

1
これは素晴らしいです。これを投稿してくれてありがとう!これにより、角かっこをエスケープしやすくなり、読みやすくなります。
phyatt

どのように私はこの仕事をしPS1=${PS1}"\e]2;$@\a"ますか。試したPS1=${PS1}"\[\e]2;\]$@\[\a\]"
ラマナレディ

59

PS1色を設定しましたよね?

カラーセットの前に引用符が\[入っていることを確認してくださいPS1

例えば:

PS1='\[\e[0;32m\u@\w/:\[\e[m '

私のPS1でしたexport PS1='^[[96m'$(hostname)'<^[[92m${PWD}^[[96m>^[[97m '-私は長い時間のための1ということを使用してきた-それは互換性のKSHだ...
BrianH

2
ワオ。私はずっと前から端末プロンプトを使用してきましたが、この問題は一度もありませんでした。それを理解することはなかっただろう。ありがとう。
bchurchill

3
単純な引用符を使用しながら\ [を使用すると、意図しないスラッシュが生成されます。また、最高の投票答えで述べたように、魔法の文字の終わりに]が使用されなければならない
igorsantos07

2
-1動作しません。最初と最後で非印刷セクションをラップする必要があります。\[\]
-wjandrea

@ igorsantos07の二重バックスラッシュは\\[、編集によるタイプミスでした。私はそれを修正しました。
-wjandrea

11

同様の問題があり、最終的に簡単な解決策を見つけました。

.bashrcファイルに次の行を追加します。

COLUMNS=250

次に、入力source ~/.bashrcして目的の効果を取得します。


狭いターミネーターの細分割など、場合によっては、問題はpromtカラー文字ではなく、間違ったCOLUMNS値にあります。この答えは私を非常に厄介な穴から抜け出させました!
カールズサラ

1
ログオフは不要です。やりますsource .bashrc。プロンプトはすぐに更新されます
Sergiy Kolodyazhnyy

1
setwinsizebashのショッピングセットがなかったので、COLUMNSが正しく更新されていなかったため、unix.stackexchange.com
a / 167911/

1
私はexport COLUMNS=250それに続いてexport TERM=xterm、それは幸せでした。
フィリップカーンズ

5

区切り文字\[とその内部にカラーコードが含まれていても、カスタムカラープロンプトで同じ問題が発生しました\]bashには、関数内から色をエコーする問題があることがわかります。最終的にプロンプ​​トに変数を使用することになり、.bashrcのエレガントさはやや劣りますが、すべてがうまく動作するようになりました。


まだこれを読んでいる人がいれば、実際には関数の色をエスケープすることができます。リンクされた質問に関するこの回答を参照してください。
-wjandrea

3

簡単なことは、PS1を設定する前に次の行を追加することです。

stty columns 1000

例えば、

stty columns 1000
PS1='\[\e[0;32m\u@\w/:[\e[m '

ただし、これはlsやmanなどの他のUNIXコマンドに影響します。


1
これはOSXで機能します。
ラスハダフィ14年

4
これはvimにも悪影響を及ぼします。これを使わないでください。
ちょうど半分

0

tmuxに接続したときにこの問題が発生しました。問題はipython、バックグラウンドでセッションがあったこと(ctrl + z)と、どういうわけか行の折り返しが壊れていたことです。終了するとすぐに(fgctrl+d+d)、端末は正常に動作し始めました

そのため、停止した対話型プロンプトを確認してください。


0

だから私は同じ問題にわずかなひねりを加えただけで、私は自分の解決策も共有するつもりだと思った、ちょっとしたニュアンスを追加するだけだ:D

私の最初のPS1は

PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$"

私が抱えていた問題は、端末のタイトルとコマンドプロンプトを変更しようとしていたことです。これを行う方法は\[\033]0;\]Title\aPS1変数に追加することでした。

だから今私のPS1は:

PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$\[\033]0;\]Title\a"

これは私にとって行の折り返しを台無しにしました。最後に、bashは\a最後に持っているのが好きではないようだと思いました。これを回避するために、タイトルを変数に入れましたが、それが修正されたようです。

TITLE="\033]0;Title\a"
PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$\[$TITLE\]"

0

\[そして\]私のために動作しませんでした。(外部プログラムから)プロンプトを生成する方法について、またはプロンプトが「動的」だったために、何か違うことがあったと思います。

これ読んだ後、0x010x02バイトで実際にカラーコードをエスケープできることがわかりました。

たとえば、特別なバージョンのチョークを使用しており、これを使用して色をラップしています:

const Chalk = require('@nasc/chalk');

const chalk = new Chalk.constructor({
  wrapper: {
    pre: '\1',
    post: '\2',
  }
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.