Bash 스크립트의 ls 문제

Bash 스크립트의 ls 문제

기본적으로 더 이상 디렉터리가 없는 디렉터리를 찾을 때까지 하위 디렉터리를 반복적으로 나열하려고 합니다. 여기서 문제는 주어진 대로 함수에 인수를 전달할 때 ls 명령이 작동하지 않는다는 것입니다. $var를 따옴표로 묶지 않으면 ls는 공백으로 구분된 문자열을 여러 인수로 처리합니다.

왜 이런 일이 발생하며 이를 방지하는 방법은 무엇입니까?

#! /bin/bash
function subdir_check(){
    local var="$*"
    ls -F -b "$var" | grep '/' | sed 's/\///g'
}
directory="$1"
if [[ $(subdir_check $directory) != "" ]]
then 
    pick=$(subdir_check $directory | rofi -dmenu -p 'Select Subdirectory')
    directory="${directory}/${pick}"
    while [[ $(subdir_check $directory) != "" ]]
    do
        pick=$(subdir_check $directory | rofi -dmenu -p 'Select Subdirectory')
        directory="${directory}/${pick}"
    done
fi
echo $directory

답변1

여기에는 두 가지 문제가 있습니다. 첫 번째는 인용문입니다. 이런 습관을 길러야 해요언제나변수를 참조하세요. 이에 대한 자세한 내용은 다음을 참조하세요.

그러나 이것이 실제로 스크립트를 손상시키는 것은 아닙니다. 다음 문제는 구문 분석을 시도할 때 발생합니다 ls. 이것이 나쁜 생각인 이유는 다음을 참조하세요.

특히 여기서 문제는 이것을 사용하면 이름이 로 표시된 -b디렉토리가 발생한다는 것 입니다 . 메뉴 선택기에서 이를 선택하면 인수 로 실행됩니다. 이것은 인용되어 있고( 함수 내에서 인용됨) 리터럴에서 실행 하려고 하기 때문에 이스케이프된 공백은 인용하기 때문에 이스케이프된 것으로 읽히지 않습니다. 그러나 인용하지 않으면 두 개의 별도 매개변수로 처리됩니다. 그래서 모든 것이 약간 혼란스럽습니다.dir onedir\ onesubdir_checkdir\ onevarlsdir\ one

다음은 약간의 수정을 가한 기본 접근 방식을 사용하는 스크립트의 작업 버전입니다.

#! /bin/bash
function subdir_check(){
  ## globs that don't match anything should expand to the empty string
  ## instead of expanding to the glob itself as happens by default
  shopt -s nullglob
  ## save all sub directories in the 'dirs' array
  local dirs=("$@"/*/);
  ## Print each dir on its own line and remove the trailing '/'.
  printf '%s\n' "${dirs[@]}" | sed 's|/$||'
}
## Remove the trailing '/' from the input.
directory=$(sed 's|/$||'<<<"$1")
## Quote all the things!
if [[ $(subdir_check "$directory") != "" ]]
then 
    ## You don't need a second variable. Just one: directory. This will now
    ## include the path.
    directory=$(subdir_check "$directory" | rofi -dmenu -p 'Select Subdirectory')
    while [[ $(subdir_check "$directory") != "" ]]
    do
        directory=$(subdir_check "$directory" | rofi -dmenu -p 'Select Subdirectory')
    done
fi
echo "$directory"

관련 정보