bash 완료가 밑줄 변수 $_를 변경하지 못하도록 방지

bash 완료가 밑줄 변수 $_를 변경하지 못하도록 방지

Bash에서 탭 완성을 사용하면 $_변수가 변경됩니다.

$ mkdir test
$ cd <TAB><TAB> $_
bash: cd: -d: invalid option
cd: usage: cd [-L|[-P [-e]]] [dir]

( <TAB><TAB>현재 디렉터리의 모든 파일이 나열되지만 출력을 사용하지 않고 $_대신 씁니다. 이 줄에서 실행되는 명령은 입니다 cd $_.)

예상되는 동작은 으로 변경되는 것입니다 ./test.

bash 완료가 변경되는 것을 어떻게 방지할 수 있나요 $_?

답변1

당신은bash-completion패키지(또는 파생물). 명령 의 각 인수 완료에 대해 cd(출력에 표시된 대로 complete -p) 다음을 수행합니다.

complete -o nospace -F _cd cd

함수 _cd는 완료를 결정하기 위해 호출됩니다(간결하게 하기 위해 약간 편집됨).

_cd()
{
    local cur prev words cword
    _init_completion || return

    local IFS=$'\n' i j k

    compopt -o filenames

    if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
        _filedir -d
        return 0
    fi
    ....

예를 들어, 설정 없이 디렉토리에서 작업을 완료하면 CDPATHvisible 명령에 대해 마지막으로 확인된 인수는 -d이고 이는 자동으로 에 배치됩니다 _. 해당 함수에는 비슷한 부작용이 있는 다른 코드 경로가 여러 개 있습니다.

bash 내부이기 때문에 _기존의 저장/복원(예:IFS) 원하는 대로 작동하지 않습니다. 너~할 수 있었다약간의 속임수를 써서 해 보세요.

_cd()
{
    local save_="$_"
    ...
    : $save_
    return 0

_함수에 진입하자마자 즉시 저장해야 합니다 . :이 명령은 자체적으로는 아무것도 수행하지 않지만 설정과 같은 명령의 일반적인 부작용이 있습니다 _. 이 복원 작업은 잠재적으로 중단을 일으킬 수 있는 각 기능의 각 반환 지점에 필요합니다. 여기에도 미묘함이 있습니다. 일반적으로 _함수에서 반환된 직후(예상대로 함수 호출의 마지막 인수로) 설정되므로 이 메서드가 효과가 없게 됩니다. 그러나 완료 함수가 호출될 때는 명시적으로 호출되지 않기 때문에 이런 일이 발생하지 않습니다. 별로 튼튼하다고는 생각하지 않습니다...

(나는 선호한다역사 확장!$, 이 문제가 발생하지 않는 것을 고수하십시오 .)

관련 정보