나는 Slackware Linux에 대해 다년간의 경험을 갖고 있지만 이 문제를 본 적이 없습니다. 나는 최근 데비안 서버를 관리하고 있는데 이것이 짜증나는 일이 되었습니다.
나는 종종 이전에 입력한 명령의 마지막 인수를 반복하기 위해 bash 명령에서 "$_"를 사용합니다. 때때로 다음과 같은 동작이 나타납니다.
dschrag@mo:~/dev/dancer$ ls -l 앱/db/schema/ 총 12개 -rw-r--r-- 1 dschrag dschrag 268 5월 19일 10:51 gau_account.sql -rw-r--r-- 1 dschrag dschrag 558 5월 19일, 13:02 gau_import.sql -rw-r--r-- 1 dschrag dschrag 270 5월 19일 13:09 gau_source.sql dschrag@mo:~/dev/dancer$ cd $_ -bash: cd: _filedir: 해당 파일이나 디렉터리가 없습니다. dschrag@mo:~/dev/dancer$
주위를 둘러보니 _filedir
에서 사용된 것이었습니다 /usr/share/bash-completion/bash_completion
.
나는 파일 완성 기능을 아무 생각 없이 사용하기 때문에 이 결함이 발생했을 때 내가 무엇을 하고 있었는지 파악하기가 어렵습니다. 이 문제를 조사하는 데 어려움을 겪은 사람이 있습니까?
답변1
프로그래밍 가능한 완료("bash 완료")를 활성화했습니다. 이는 소스 /etc/bash_completion
나 bashrc의 어딘가를 통해 /usr/share/bash-completion/bash_completion
수행 됩니다. 예를 들어, jessie의 bashrc 스켈레톤에서는 다음과 같습니다.
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
완료되는 작업 중 하나는 멀칭입니다 $_
. 빠른 수정은 bash 완성을 로드하지 않는 것입니다.
complete-filename
또 다른 해결 방법은 이 함수 대신 이 함수를 사용하여 파일 이름 완성을 완료하는 것입니다 complete
. 이는 대신 ESC, /또는 Alt+ /(단말기 설정에 따라) 를 누르는 것을 의미합니다 Tab. bind
를 사용하거나 편집하여 이러한 키가 바인딩된 키를 변경할 수 있습니다 ~/.inputrc
.
또한 bash 완성에 대한 버그 보고서를 제출하고 싶습니다.
답변2
단순 추적
cd
먼저, bash 명령 완성을 사용할 때 실제로 무슨 일이 일어나는지 알아낼 수 있습니다 .
$ complete -p | grep cd
complete -F _filedir_xspec cdiff
complete -o nospace -F _cdrecord wodim
complete -o nospace -F _cdrecord cdrecord
complete -o nospace -F _cd cd
_cd
완성을 사용하면 함수가 호출되는 것을 볼 수 있습니다 cd
. 따라서 _cd
함수 내부에서 $_
변수 값이 변경된 문제가 발생했다는 것을 알 수 있습니다 .
기능을 확인하세요 _cd
: (내 Ubuntu 12.04.4에서는 /etc/bash_completion
)
# This meta-cd function observes the CDPATH variable, so that cd additionally
# completes on directories under those specified in CDPATH.
#
_cd()
{
local cur IFS=$'\n' i j k
_get_comp_words_by_ref cur
# try to allow variable completion
if [[ "$cur" == ?(\\)\$* ]]; then
COMPREPLY=( $( compgen -v -P '$' -- "${cur#?(\\)$}" ) )
return 0
fi
....
_filedir -d
if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
i=${COMPREPLY[0]}
if [[ "$i" == "$cur" && $i != "*/" ]]; then
COMPREPLY[0]="${i}/"
fi
fi
return 0
}
$_
그것은 당신이 옛 자아를 잃게 만드는 많은 일을 할 것입니다 . 아마도 배선에 문제가 있는 것 같습니다 _filedir -d
. (내 테스트에서는 $_
로 변경되었습니다 -d
.)
원하는 내용을 잃지 않으려면 함수에 들어가자마자 해당 값을 저장한 다음 $_
종료하기 전에 _cd
복원 할 수 있습니다.$_
_cd
_cd()
{
local __=$_
....
: $__
return 0
}
여기서 중요한 점은 :
에서 아무 작업도 하지 않고 매개변수 (원하는 값 ) bash
가 있어서 함수를 입력하기 전에 이전 값으로 설정된다는 것입니다.$__
$_
$_
_cd
결론적으로
bash completion
변수를 낭비하지 않는 것은 매우 어렵습니다 $_
. 위의 예에서는 를 사용합니다 . cd
의 다른 기능 bash_completion
과 아래의 모든 파일에 대해서도 /etc/bash_completion.d/
동일한 작업을 수행해야 합니다 . 이는 신뢰할 수 있는 솔루션이 아닙니다.
마지막 명령줄의 마지막 인수를 얻으려면 다음을 사용해 보십시오 bash history expansion
.
$ echo 1 2 3
1 2 3
$ echo !$
echo 3
3