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
    ....

예를 들어, CDPATH설정되지 않은 디렉토리를 완료하면 명령에 대해 마지막으로 확인된 인수는 -d이며 자동으로 에 배치됩니다 _. 이 함수에는 유사한 부작용이 있는 다른 여러 코드 경로가 있습니다.

bash 내부에 있기 때문에 _전통적인 저장/복원(예:IFS) 원하는 대로 작동하지 않습니다. 너할 수 있다이를 수행하려면 약간의 트릭을 사용하십시오.

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

_함수에 들어가자마자 저장 해야 합니다 . :이 명령은 자체적으로는 아무것도 수행하지 않지만 설정과 같은 명령의 일반적인 부작용이 있는 빈 명령입니다 _. 이 복구 작업은 잠재적으로 파괴적인 모든 기능의 모든 반환 지점에 필요합니다. 여기에도 미묘함이 있습니다. 일반적으로 _함수가 반환된 직후(예상대로 함수 호출의 마지막 인수로) 설정되어 메서드가 무효화됩니다. 하지만 완성 함수를 호출할 때는 명시적으로 호출되지 않기 때문에 이런 일이 발생하지 않습니다. 별로 강력한 힘은 아닌 것 같은데...

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

관련 정보