Bash 자동 완성: 다른 디렉터리의 파일 및 디렉터리 나열

Bash 자동 완성: 다른 디렉터리의 파일 및 디렉터리 나열

prpsls나는 디렉토리에 파일을 생성하거나 편집하는 스크립트를 작성했습니다 ~/proposals.

이제 이에 대한 자동 완성 스크립트를 작성하고 있으며 클릭한 후 다음과 같은 방식으로 설정하려고 합니다.상표, 현재 작업 디렉토리에 관계없이 complete디렉토리의 파일과 디렉토리를 나열하는 내장 기능입니다 .~/proposals

내가 달성하고자 하는 동작은 내가 한 것과 정확히 동일 complete -f prpsls하지만, 현재 디렉토리의 파일과 디렉토리를 나열하는 대신 항상 디렉토리의 내용을 완료하기를 원합니다 ~/proposals.

예를 들어, 내가 글을 쓸 ls상표, 다음을 나타냅니다.

$ pwd
/home/user/base_directory
$ ls
file_01   file_02    subdir_01/

내가 글을 subd쓰고상표, 다음과 같이 자동으로 완료됩니다 subdir_01.상표다시 말하지만, 이것이 보여주는 것입니다 dir_01:

$ ls subdir_01/
file_03    subdir_02/

내가 찾고 있는 행동은 다음과 같습니다.

$ pwd
/home/user/any/directory/it/should/not/matter
$ prpsls # Tab here
proposal_01    proposal_02    job_01/
$ prpsls job_01/ # Tab again
proposal_03    proposal_draft

complete내 질문은: 내장 기능을 통해 이 동작이 가능합니까? 그렇지 않다면 어떻게 이 동작을 달성할 수 있습니까?

complete기본 디렉토리로 사용할 디렉토리를 플래그를 통해 알 수 있었으면 좋겠지 만 디렉토리 목록을 생성하는 -dwhich 와 동일한 디렉토리 관련 플래그만 표시됩니다 -A directory.

흥미롭게도 내가 compgen -f "~/proposals/"사용 하면하다다음 위치의 파일 및 디렉터리 나열 ~/proposals:

$ pwd
/home/user/any/directory/it/should/not/matter
$ compgen -f "~/proposals/"
~/proposals/job_01
~/proposals/proposal_01
~/proposals/proposal_02

나는 보았다이것그러나 질문은 다음과 같습니다.

  • 허용된 답변은 중첩된 디렉터리에서는 작동하지 않습니다. (즉상표디렉토리의 내용을 봅니다.)
  • 대답은 CDPATH다른 명령에 더 많은 혼란을 가져올 것입니다.
  • 대답은 compgen중첩된 디렉토리에서도 작동하지 않습니다.

답변1

기반으로이 훌륭한 답변foo파일과 디렉터리를 재귀적으로 완성하는 command 에 대해 다음 완성을 작성했습니다 ~/foodir.

FOO_DIR=$HOME/foodir/

_foo_compgen_filenames() {
    local cur="$1"

    # Files, excluding directories:
    grep -v -F -f <(compgen -d -P ^ -S '$' -- $FOO_DIR"$cur") \
        <(compgen -f -P ^ -S '$' -- $FOO_DIR"$cur") |
        sed -e 's|^\^'$FOO_DIR'||' -e 's/\$$/ /'

    # Directories:
    compgen -d -S / -- $FOO_DIR"$cur" | sed -e 's|'$FOO_DIR'||'
}

_foo_complete() {
    local cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $(_foo_compgen_filenames "$cur") )
}

complete -o nospace -F _foo_complete foo

비결은 compgen완성 엔진이 완성에서 파일의 전체 경로를 완료하도록 한 FOO_DIR다음 FOO_DIR완성에서 해당 경로를 로 보내기 전에 제거하는 것 입니다 complete. 또한 디렉토리 이름 끝에 슬래시를 추가하는 문제도 있습니다. 이는 지정되지 않은 것이며 compgen파일만 반환하는 기본 방법은 없습니다(그러나 디렉토리만 반환하는 방법은 실제로 있습니다).

답변2

나는 그것을 고치는 방법에 대한 몇 가지 방법과 아이디어를 시도하고 찾았습니다.

전문가는 내 방식을 개선하고 더 나은/완벽한 솔루션을 만들 수 있습니다.

내 시스템은 KDE와 GNOME이 포함된 Debian GNU/Linux 10(buster) 4.19.0-16-amd64입니다.

첫 번째 부분:

  1. 새 셸 시작

  2. 작업 디렉터리를 만들고 /home/user/ComBash입력 cd하세요.

  3. mytab전체 명령에 바인딩할 스크립트를 만듭니다.

    이제 mytab다음과 같습니다:

    #!/bin/bash
    echo "MYTAB"
    
  4. chmod +x mytab

  5. px전체 명령에 대한 두 번째 스크립트 만들기

    이제 px다음과 같습니다:

    #/usr/bin/env bash
    echo "PX"
    
  6. chmod +x px

  7. px이제 스크립트를 시작해 보겠습니다.

    source px
    

    또는

    ./px
    

    또는

    . ./px
    

    출력은 "PX"여야 합니다(작동함).

  8. bin/이름이 다음인 새 폴더를 만듭니다./home/user/ComBash

    mkdir bin
    

    우리 파일은 이제

    mytab        | script
    px           | script
    bin/         | folder
    
  9. 이제 workdir 경로 mytab에 설치 하고 제거하십시오.bin//home/user/ComBash/binmytab/home/user/ComBash/

    install mytab bin/mytab && rm mytab
    
  10. 이제 bin/workdir 폴더를 추가하십시오.$PATH

    PATH="/home/user/ComBash/bin:${PATH}"
    

    또는

    PATH="${PATH}:/home/user/ComBash/bin"
    

    확인해보세요

    echo $PATH 
    
  11. mytab작동하는지 확인하십시오 .

    • myt+ TAB를 누르고Enter
    • mytab~에 따르면Enter
    • 출력은 "MYTAB"입니다(작동함).
  12. 폴더 안에 폴더, 하위 폴더 및 빈 파일을 만듭니다. TAB+가 유효한지 TAB확인하고 TAB|TAB에 표시되는 내용을 확인하려면 이러한 폴더와 파일이 필요합니다.

이제 두 번째 부분의 구조가 완성되었습니다. 솔루션은 현재 셸에서만 작동합니다.

새 셸을 닫고 시작하면 /home/user/ComBash/binin 이 $PATH제거되고 bash는 mytab에서 스크립트를 찾을 수 없습니다 /home/user/ComBash/bin. 그러면 새 셸이 시작될 때마다 9단계($PATH 설정)를 반복해야 합니다.

셸을 시작할 때마다 9단계를 반복하지 않으려면 영구적으로 추가할 수 있습니다 /home/user/ComBash/bin.$PATH

두 번째 부분:

  1. px파일 열기 및 편집

    나는 또한 이 명령을 많이 시도했지만 지금은 설명하지 않을 것입니다. 결과를 보려면 시도해 볼 수 있습니다. 시도하려는 줄의 주석 처리를 제거하고 편집하면 됩니다.

    이제 px는 다음과 같습니다:

    #/usr/bin/env bash
    #complete -f mytab
    #complete -D -F "/home/user/ComBash" mytab
    #complete -W "$(find /home/user/ComBash/ -path "" -prune -o \( -type d -ls \) -o \( -type f -ls \) | cut -d/ -f 5-)" mytab
    #complete -W "$(find /home/user/ComBash/ -path "" -prune -o \( -type d -ls \) -o \( -type f -ls \) | cut -d/ -f 2- | sed 's/$/\//')" mytab
    #complete -W "$(find /home/user/ComBash/ -path "" -prune -o \( -ls \)))" mytab
    #complete -W "$(ls -R ${MYPATH} | grep /)" mytab
    MYPATH="/home/user/ComBash/"
    complete -W "$(ls -R ${MYPATH})" mytab
    

    전체 명령을 mytab스크립트 에 바인딩합니다.

    -W전체 단어 목록을 제공한다는 뜻입니다.

    우리는 로 단어 목록을 얻습니다 ls -R.

    ls -R지정된 경로의 모든 파일, 하위 파일, 디렉터리 및 하위 디렉터리를 나열합니다.

  2. px 스크립트를 시작합니다

    source px
    

    스크립트 내에서 변경 사항이 있을 때마다 스크립트를 다시 시작해야 합니다(1부의 6단계 참조).

    source px 
    
  3. 이제 우리가 사용하는 쉘에서

    mytab+TAB

    /home/user/ComBash/주어진 경로( )에 있는 모든 파일, 하위 파일, 디렉터리 및 하위 디렉터리의 목록을 볼 수 있습니다.

    모든 파일, 하위 파일, 디렉터리 및 하위 디렉터리를 선택하고 [TAB]을 사용하여 자동 완성할 수 있습니다.

    유효한 하위 폴더를 선택하고 [TAB]을 누르세요.

    누르면 Enter스크립트는 mytab"MYTAB"을 에코합니다.

  4. mytab에서 스크립트를 편집해 보겠습니다 /home/user/ComBash/bin.

    이제 mytab다음과 같습니다:

    #!/bin/bash
    MYPATH=/home/user/ComBash
    # echo $MYPATH
    echo $1
    DATA=$(find ${MYPATH} -name ${1})
    echo $DATA
     ####### DO SOMETHING #######
    

    $1px스크립트 검색에서 받은 폴더나 파일을 출력 DATA하고 PATH해당 폴더나 파일의 내용 을 출력합니다.

이제 현재 파일이나 폴더에 대해 특정 작업을 수행할 수 있습니다.

mytab+ Tab누르기Enter

관련 정보