現在の問題

現在の問題

次の100行をターミナル(xterm)にコピーして貼り付けて、接続されたサーバーで実行しましたssh

mv /long/path/to/file1 /longer/path/to/file1
mv /long/path/to/file2 /longer/path/to/file2
...
mv /long/path/to/file99 /longer/path/to/file99
mv /long/path/to/file100 /longer/path/to/file100

残念ながら、コピー/貼り付け後に100個のファイルが見つかりません。/longer/path/to/

SSHを介して接続されているサーバーのbash履歴を見ると、最初の20個のコマンドの後にほとんどのコマンドが切り捨てられることがわかります。

mv /long/path/to/file1 /longer/path/to/file1
...
mv /long/path/to/file20 /longer/path/to/file20
mv /long/path/to/fi
mv /long/path/to/fi
mv /long/path/to/file23 /longer/p
mv /long/path/to/file24 /longer/path
mv /long/path/to/file25 /longer/p
mv /long/path/to/file26 /longer/p
mv /long/path/to/file27 /longer/path/t
mv /long/path/to/file28 /longer/path/to/fil
mv /long/path/to/file29 /longer/path/to/fil
mv /long/path/to/file30 /longer/path/to/file
mv /long/path/to/file31 /longer/path/to/file
...

この問題を解決する方法の答えを見つけることができます。

しかし、正確に何が起こっているのかについての説明が見つかりません。特に:

  • これは端末関連の問題ですか(私の場合はXterm)?
  • コピー/貼り付けの発生場所ssh:これは問題を引き起こしたり増幅したりしますか?
  • これはサーバーのbash関連の問題ですか?別のシェルを使用している場合、これは起こらないかもしれませんか?

答え1

次のエラーが発生したようです。

https://lkml.org/lkml/2013/7/25/205

ラインルールバッファを超えて4k以上を貼り付けると、readline()が誤ってエラー回復パスをトリガーしました。エラーリカバリパスは、ラインルールバッファがいっぱいになり、標準モードで実行されており、改行文字が受信されない場合は入力を削除します。 readline() はラインを文字ごとに読み取るために termios を非正規モードに変更するため、ラインルールバッファがいっぱいになる可能性があります。です。 Zoneでエラーが発生します。回復。

非キヤノンモードからキヤノンモードにtermioを変更すると、EOFプッシュをシミュレートし、読み取りバッファにデータが含まれます。いいえバッファから DISABLED_CHAR を読み込みます。

readline() の問題に関しては、読み取りバッファを変更せずに termios を非正規モードに戻すことができることが重要です。つまり、以前のtermiosの変更が発生していないように見えます(中間読み取りが発生しない限り)。 )。

これは2013年12月10日、Linuxカーネル3.14としてカーネルに実装されました。以前のLinuxディストリビューションを使用していますか?あなたのディストリビューションは何ですか?おそらく実際のパスをファイルに置き換えたので、文字数を実際に数えることはできません。次のことができます。

for ((a=1; a<20; a++)); do echo "mv /long/path/to/file$a /longer/path/to/file$a"; done|wc -c

実際のルートを使用すると、本当に4Kに近いものになりますか?その場合、上記のエラーはあなたのエラーかもしれません。

もしそうなら、あなたの質問に答えてください。

  • これは端末関連の問題ですか(私の場合はXterm)?

いいえ

  • SSH経由でコピー/貼り付け:これは問題を引き起こしたり増幅したりしますか?

いいえ

  • これはサーバーのbash関連の問題ですか?

いいえ、本当です。これはbashやbashで使用されるライブラリのバグではありません。カーネルにバグが存在します。

  • 別のシェルを使用している場合、これは起こらないかもしれませんか?

おそらく、シェルがreadlineを使用していない場合です。 zshと同じです。

関連質問「複数の犬を貼り付ける方法…」については問題とは関係ないようです。その理由は、一部のアプリケーションが貼り付けたコマンドを読み取ることができるためです。最も有名な例は、リモートサーバーでsshコマンドを実行する場合のsshです。しかし、ラインの一部だけが失われていることを考慮すると、あなたのケースでは不可能です。

2番目の質問「ターミナルに貼り付けるコマンド...」は、2013年9月25日にパッチが存在しなかったときに要求されました。

確実に確認する方法は? uname -aの出力をここに貼り付けます。

答え2

現在の問題

コピーして貼り付けたコード行が切り捨てられる理由を知りたいです。

あなたの質問を調べたところ、Bashには通常デフォルトで行制限があることがわかりました。これはおそらくあなたの問題である可能性が高いです。ただし、提供した例では、線が異なる長さに切り取られることを示しています。私はこの状況を打開するために最善を尽くします。

解決策

1. これは端末関連の問題ですか(私の場合はXterm)?

これは可能ですが、これはxtermではなくデフォルトのBash環境の制限によるものです。 (xtermの多くのデフォルト値を変更しない限り)

切り捨てを減らすために、行の長さを増やすソリューションを提供する次の記事を参照しています。このU&Lスタック交換回答端末エミュレータの期待に合わせてウィンドウのサイズを変更する方法について説明します。ユーザーaketrpは、端末がウィンドウサイズを正しく解釈していることを確認するためにこのソリューションを提供しました。

bashを使用している場合は、これを試してみてください。

$ shopt checkwinsize

得られないと

checkwinsize    on

その後、有効にしてください

$ shopt -s checkwinsize

それから私は別のコマンド(たとえばls)を実行したり、ウィンドウサイズを一度調整したりしましたが、上記の方法は毎回私にとって効果的でした。

特にRedhatシステムの場合、この問題は通常/etc/bashrcを呼び出さずに~/.bashrcを誤って設定したために発生します。通常、bashは~/.bashrcをロードします。これはデフォルトでshopt -s checkwinsizeを含む/etc/bashrcを呼び出すと予想されます。

ただし、これは実際の行長ではなくウィンドウサイズの解釈にのみ影響します。利用時に提供される情報このAskUbuntuの投稿shopt正しく設定したら、次の行を追加して行の.bashrc長さを増やすことができます。

COLUMNS=250

source .bashrcBash設定ファイルを更新するには実行してください。

2. SSH経由でコピー/貼り付け:これは問題を引き起こしたり増幅したりしますか?

根本的な原因ではなくても、これが問題の一部だと言いたいです。あなたがつながった解決策は、これが起こらないようにするための確実な解決策です。

コマンドセットをコピーして貼り付ける必要がある場合(複数回使用する必要がありますか?)、そのコマンドセットのBashスクリプトを生成することをお勧めします。次にscp、、sftpEメール、またはその他の方法を使用して、curl使用したいファイルをリモートで送信します。

これにより、リンク解決方法に記載されている切り捨ての問題を完全に回避でき、生成および/または複数のサーバーへの転送を同時にスクリプト化できます。

3.サーバーにbash関連の問題がありますか?別のシェルを使用している場合、これは起こらないかもしれませんか?

言及した通りです。これは、Bashプロファイル設定によって設定された行制限に問題がある可能性があります。他のシェルにはこの問題はないかもしれませんが、私はDash / Bashにのみ慣れています。ただし、本番サーバーまたはレガシーシステムの場合は、環境変数の変更を開始すると常に機能しない可能性があります。不可能ではありませんが、一部のパッケージ/ソフトウェア/古いスクリプト/cronjobがBashをデフォルトのシェルとして使用している場合、リスクがあり、それを変更すると結果が発生する可能性があります。

もう一度お話しますが、この問題を解決するには、実行したいコマンドのスクリプトを生成し、それをリモートサーバーに送信してそこで実行することをお勧めします。

結論として

コマンドが切り捨てられる理由は、環境、Bashプロファイル設定、ターミナルエミュレータ設定、およびコマンドをコピーして貼り付ける方法によって異なります。指摘されているように、いくつかの回避策があり、問題を回避するためにスクリプトと一緒に使用することをお勧めします。私もxtermマンページリンクこれにより、変更できる他の設定やオプションがあることを確認できます。

この回答について質問や質問がある場合は、コメントを残してください。誤解を解決し、投稿を改善するためにフィードバックを送信していただきありがとうございます。必要に応じて回答を更新できます。

頑張ってください!

答え3

ある端末から別の端末にコマンドをコピーするには、gzipとbase64を使用することをお勧めします。メタ文字やタブの拡張によって問題が発生した場合は、この方法で解決する必要があります。

例:

[root@server-one ~]# cat << __EOF__ | gzip | base64
mv /long/path/to/file23 /longer/p
mv /long/path/to/file24 /longer/path
mv /long/path/to/file25 /longer/p
<other commands>
__EOF__

その後、エンコード結果をコピーして

[root@server-two ~]$ base64 -di | gunzip | bash
<insert your base64-encoded and send with control-d>

関連情報