Bash Tab Completion : '-bash :`)'을 찾는 동안 예기치 않은 EOF가 발생했습니다. -bash : 구문 오류 : 예기치 않은 파일 끝


18

irb이 명령으로 파일에서 특정 환경 변수가있는 세션 으로 이동하려고합니다 .

$ env $(cat env.sh) irb

그러나 Tab입력 한 후 프레스 를 시도 env.하면 다음과 같은 오류가 발생합니다.

$ env $(cat env.-bash: unexpected EOF while looking for matching `)'
-bash: syntax error: unexpected end of file

또 다른 흥미로운 점은 루트로 로그인 한 경우이 오류가 발생하지 않는다는 것입니다.

출력은 다음과 같습니다 find ~ -uid 0.

$ find ~ -uid 0
/home/(redacted)/.rpmdb
/home/(redacted)/.rpmdb/Group
/home/(redacted)/.rpmdb/Conflictname
/home/(redacted)/.rpmdb/Installtid
/home/(redacted)/.rpmdb/Sha1header
/home/(redacted)/.rpmdb/Providename
/home/(redacted)/.rpmdb/__db.002
/home/(redacted)/.rpmdb/Requirename
/home/(redacted)/.rpmdb/Sigmd5
/home/(redacted)/.rpmdb/__db.001
/home/(redacted)/.rpmdb/Obsoletename
/home/(redacted)/.rpmdb/.dbenv.lock
/home/(redacted)/.rpmdb/Name
/home/(redacted)/.rpmdb/Basenames
/home/(redacted)/.rpmdb/Triggername
/home/(redacted)/.rpmdb/Packages
/home/(redacted)/.rpmdb/Dirnames
/home/(redacted)/.rpmdb/__db.003

누구나 왜 이런 일이 발생하는지 설명 할 수 있습니까? 그렇다면 루트 사용자가 아닌 경우 어떻게 수정합니까?


루트로 어떻게 로그인합니까?
muru

@muru 나는를 사용하여 루트에 로그인했다 sudo su.
eldosoa

의 출력을 추가하려면 질문을 편집하십시오 find ~ -uid 0.
muru

@muru 완료. 내 질문에 출력을 추가했습니다.
eldosoa

그것에 대해 죄송하지만 루트가 아닙니다! 그 때문에 나는, 일반 사용자로 의미 ~입니다 /home/something.
muru

답변:


33

우분투에서 사용 하는 Bash Completion 라이브러리 에서 버그를 발견했습니다 .

이것은 무엇을 의미 하는가?

우분투는 bash 완성 라이브러리를 사용하여 bash 완성을 똑똑하게 만듭니다. 이 도서관은에 /usr/share/bash-completion/bash_completion있습니다.

기본적으로이 라이브러리는 일반적인 명령과이를 완료하는 방법을 알고있는 영리한 함수를 선언합니다. 를 누를 때마다이 Tab라이브러리 내의 함수가 호출되어 현재 명령 행을 완료하려고 시도합니다. 예를 들어 입력 apt-get iTab하면을 (를) 완료합니다 apt-get install. 해당 라이브러리를 소싱하지 않으면 표준 기본 bash 완성 만 있습니다. 예를 들어 apt-get iTab소싱하지 않고 입력하면 bash는 현재 디렉토리에서 시작하는 파일 i을 찾은 다음에 따라 명령을 완료하려고 시도합니다. 이 파일 이름.

왜 루트로 발생하지 않습니까?

sudo su자신을 만드는 데 사용할 때 rootbash 완료 라이브러리는 소스가 아니기 때문입니다. 당신 sudo -i이 자신 을 사용 하는 경우 이것은 다를 것 root입니다. 그때 당신은 벌레를 보지 않겠습니까? 예를 들어 'sudo su-'vs 'sudo -i'vs 'sudo / bin / bash'를 참조하십시오. 사용되는 것이 언제 중요합니까, 아니면 전혀 중요합니까? 차이점에 익숙하지 않은 경우

필자의 경우 일반적인 사용자로서 ~/.bashrc소스 /etc/bash_completion가 소스 이기 때문에 Bash 쉘을 시작할 때 라이브러리가 소스됩니다 /usr/share/bash-completion/bash_completion.

sudo -i로 로그인 하는 데 사용 하는 경우 소스 root는 소스로 인해 /etc/profile소스 /etc/profile.d/bash_completion.sh가됩니다 /usr/share/bash-completion/bash_completion.

왜 그 버그가 발생합니까?

이 명령을 실행하십시오 :

$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file

익숙해 보이나요? ;-) 사실, 그것은 Tab당신이 묘사 한 맥락에서 맞을 때 장면 뒤에서 일어난 일 입니다. 보다 정확하게는 버그가에 _quote_readline_by_ref의해 선언 된 함수 에 /usr/share/bash-completion/bash_completion있습니다. 해당 파일을 소싱 한 경우 해당 기능을 사용할 수 있어야합니다. 다음에 이것을 시도하십시오 :

$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file

이러한 주장을 감안할 때, 함수는 _quote_readline_by_ref무엇보다도 eval위에서 언급 한 기능을 수행합니다 . 당신이 좋아하면 볼 수 있습니다. 그리고 당신이 타이핑했을 때 env $(cat env.Tab, 그 함수 뒤에서 함수는 정확히 그 인수로 호출되었습니다. 그래서 그 일이 일어났습니다.

eval해킹 은 또 다른 문제를 해결하기로되어 있었지만 프로세스에서이 다른 버그를 소개했다고 생각합니다.

어떻게 고치나요?

이 버그 는 이미보고 된 것으로 밝혀졌습니다 . 해당 버그 보고서를 읽은 후 세 가지 방법으로 문제를 해결할 수 있습니다.

  1. 패치 : 해당 버그 보고서의 의견 중 하나에서 누군가가 줄 바꾸기를 제안합니다.

    [[ ${!2} == \$* ]] && eval $2=${!2}

    함수 내 _quote_readline_by_ref파일의 /usr/share/bash-completion/bash_completion라인에 의해

    [[ ${!2} == \$\'* ]] && eval $2=${!2}

    나는 이것을하지 않는 것이 좋습니다. 그 의견을 쓴 사람 은 bash-completion의 개발자 가 아닌 것 같습니다 . 이 핫픽스는 단순히 명령문의 왼쪽 피연산자가 false로 평가되어 eval발생 하지 않도록합니다 . 그러나 그 기능이 무엇을해야하는지, 어떤 맥락에서 호출되는지에 대한 지식이 없으면, 이것이 의도 한 다른 기능을 잠재적으로 중단시키지 않을지 불분명합니다.

  2. 최신 버전 받기 : 해당 버그 보고서에서 언급했듯이이 버그는 git head에는 없습니다 (다른 변경 사항 중에서도 기능 _quote_readline_by_ref이 단순화되었습니다). Git에서 현재 버전을 간단히 복제 할 수 있습니다.

    git clone https://salsa.debian.org/debian/bash-completion.git

    ... 그리고 최신 버전의 bash_completion스크립트를 복사하십시오 /usr/share/bash-completion(더 안전하다고 느끼지 않는 한 이전 버전을 긴급하게 백업 할 필요가 없습니다. 문제가 발생 sudo apt-get install --reinstall bash-completion하면 변경 사항을 되돌려 야합니다). 이 문제를 해결하기 위해 서두르는 것이 좋습니다. :-)

이러한 솔루션 중 어느 것도 명령 대체 작업 내에서 bash 완료를 수행하지 않습니다. 동일한 버그 보고서에서 언급했듯이 Bash 4.3에서는이 문제가 해결되었습니다.

  1. 편안히 앉아 기다리십시오. 조만간 새로운 버전이 출시되고 (명령 대체에서 bash 완료 문제를 해결할 수도 있음) 향후 Ubuntu 버전을 사용하게됩니다. 그게 내가 갈거야 ;-)

1
@ con-f-use 그렇습니다! Git 리포지토리는 bash-completion 의 주요 사이트 와 연결되어 있기 때문에 대답하지 않았습니다.
Malte Skoruppa

2
@ con-f-use 귀하의 의견으로이 버그에 대해 더 많은 연구를하게되었습니다. 그것은 업스트림 버그가 아니며 결코 아니 었습니다. 대신, 실제로는 업스트림 버전에 적용된 우분투 패치로 인해 발생한 버그입니다. 지금까지이 버그를 특정 패치로 좁힌 사람은 없습니다. 따라서 해당 우분투 버그 보고서에서 버그를 발견했습니다 : bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1312243 .
Malte Skoruppa 2016 년

2
잘 했어 몰타
Barry Kelly

1
설명 주셔서 감사합니다. 이 기입으로, 자식 헤드 버전 버그 제거한 하고 원하는대로 자동 완성한다. 편집 : 실제로, 신경 쓰지 마십시오.
user3391564

1
@MaxvonHippel 난 당신이 사용하는 경우 말했다 sudo su루트가되고, 그것이이 라이브러리 소스,하지만하지 않습니다 사용할 때 공급받을 sudo -i대화 형 루트 세션을 얻을 수있는 구성 방법 인 대신. 귀하의 질문에 관해서 : 모든 bash 쉘은 ~/.bashrc결국 라이브러리를 소스로 지정하고 파일을 "소스 해제"하는 방법이 없으므로 완전히 직접적인 방법은 없습니다. 다음은 가능한 해킹의 : 일부 환경 변수에 라이브러리 조건의 소싱을 확인, 말하자면 NOCOMPL, 하지 귀하에 정의되고 ~/.bashrc, ...
말테 Skoruppa
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.