다음 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를 비정규 모드로 변경하기 때문에 라인 규칙 버퍼가 가득 차게 될 수 있으며, 그런 다음 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입니다. 그러나 라인의 일부만 손실되고 있다는 점을 고려하면 귀하의 경우에는 불가능합니다.
두 번째 질문인 "터미널에 붙여넣기 명령..."은 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 .bashrc
Bash 구성 파일을 업데이트하려면 실행하세요 .
2. SSH를 통해 복사/붙여넣기: 이로 인해 문제가 발생하거나 증폭됩니까?
근본 원인은 아니더라도 이것이 문제의 일부라고 말하고 싶습니다. 귀하가 연결한 해결 방법은 이러한 일이 발생하지 않도록 하는 확실한 솔루션입니다.
명령 세트를 복사하여 붙여넣어야 하는 경우(여러 번 사용해야 합니까?) 해당 명령 세트의 Bash 스크립트를 생성하는 것이 좋습니다. 그런 다음 scp
, , sftp
이메일 또는 기타 방법을 사용하여 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>