Bash 스크립트에서 문제 찾기

Bash 스크립트에서 문제 찾기

나는 지정된 디렉토리의 파일과 디렉토리를 인쇄하는 프로그램을 작성하고 있습니다. 하지만 특정 유형의 파일은 무시해야 합니다. 우리는 그것들을 .ignorefile.

그래서 원하는 파일을 얻기 위해 찾기 기능을 사용합니다. 그러나 매번 같은 오류가 발생합니다 No such file or directory.

또한 터미널에서 시도해 보면 동일한 매개변수로 완벽하게 작동합니다.

한 가지 예:

  • 내 무시 파일에는 다음이 있습니다.*.txt, *.cpp

  • .sh파일을 실행할 때 파일 무시와 디렉터리 무시라는 두 가지 매개변수를 입력합니다.

  • 그런 다음 파일의 모든 텍스트를 스캔하여 매개변수 파일을 구성할 때 함수를 호출합니다 store().

여기에서 내 코드를 볼 수 있습니다.

    function store(){
      dir="$1" 
      find_arg="$2" # Dir ! -name '*.txt' ! -name '*.cpp' -print
      echo $find_arg
      cmd=`find "$find_arg"`
      echo $cmd
    }

find_args를 빌드하는 함수는 다음과 같습니다.

function backup()
{
  if [ $1="-i" ] && [ -f $2 ]
  then
    backignore=$2
    if [ $3="-d" ] && [ -d $4 ]
    then
      directory=$4
      find_arg=" $directory"
      while IFS='' read -r line || [[ -n "$line" ]]; do
        find_arg+=" ! -name "
        find_arg+="'"
        find_arg+=$line
        find_arg+="'"
      done < "$backignore"
      find_arg+=" -print"
      store $directory "$find_arg"
    else
      echo "please entrer a right directory"
    fi
  else
    echo "Please enter a right ignore file"
  fi
}

backup $1 $2 $3 $4

나는 그것을 "sh" 파일이라고 부른다.

./file.sh -i ignorefile -d Source

산출:

Source ! -name '\*.cpp' ! -name '\*.txt' -print
Source/unix_backup/example_files/backignore   
Source/unix_backup/example_files/Documents/rep1/file3.txt
Source/unix_backup/example_files/Documents/rep1/file4.cpp   
Source/unix_backup/example_files/Documents/rep3 
Source/unix_backup/example_files/Documents/rep3/rep4 
Source/unix_backup/example_files/Documents/rep3/rep4/file7.txt    
Source/unix_backup/example_files/Documents/rep3/rep4/file8.cpp

답변1

find_arg단일 인수로 전달됨(큰따옴표 때문에) 이는 다음을 의미합니다.find찾으려고 노력 중모두파일은 이름 아래에 있습니다.Dir ! -name '*.txt' ! -name '*.cpp' -print(예, 유효한 디렉터리 이름입니다.) printf '%q\n' "$find_arg"에 전달된 실제 매개변수를 확인해 보세요 find. 또한 쉘이 배열을 지원한다면 아마도매개변수를 저장하는 데 사용합니다.. 그리고더 많은 인용문 사용™! eval여기서는 사용 하지 마세요 . find파일 이름이 제대로 인쇄됩니다.

답변2

  1. .ignorefile에 이 파일이 있다고 말했지만 *.txt, *.cpp표시된 출력에서는 그런 것처럼 보입니다 \*.txt, \*.cpp. 이스케이프는 *문제의 원인이며, find별표를 전역 와일드카드로 사용하는 대신 문자 그대로 별표가 있는 파일을 제외하도록 지시합니다. 그러니 하지 마세요.

  2. 이 버전의 스크립트는 일부 버그를 수정하고 약간 단순화했습니다. 무엇보다도 backup()함수의 기본 논리 에서 arg 처리(그리고 sh의 내장 getopts 사용)를 분리합니다 .

function store() {
    echo find "$@"
    find "$@"
}   

function backup() {
  directory="$1"
  backignore="$2"

  # skip comments and blank lines
  sed -e 's/#.*// ; /^[[:space:]]*$/d' "$backignore" |
      while IFS= read -r line ; do
          find_arg+=" ! -name '$line'"
      done 
  find_arg+=" -print"
  store "$directory" $find_arg
} 

usage() { 
    echo "$(basename $0) [ -d directory ] [ -i ignorefile ]"
    exit 1
}   

directory=''
backignore='.ignorefile'    # default

while getopts "i:d:h" opt ; do
  case "$opt" in
    d)  directory="$OPTARG" ;;
    i)  backignore="$OPTARG" ;;
    *) usage ;;
  esac 
done

[ -z "$directory" ] && echo "Please provide a directory." && usage

backup "$directory" "$backignore"

관련 정보