디렉토리에 파일이 있는지 확인

디렉토리에 파일이 있는지 확인

안녕하세요, 저는 디렉터리 경로를 매개변수로 사용하고 file.txt가 디렉터리에 있는지 확인하는 if 작업을 수행하려고 합니다. 그렇다면 1을 반환하고, 그렇지 않으면 0을 반환합니다.

     if [ -e $1/file.txt ]; then
         exit 1
     else exit 0
     fi

나는 또한 ls 방법을 시도했습니다

     ls $1/file.txt && exit 1 || exit 0

다른 방법이 있나요? 아니면 내가 뭔가를 놓치고 있는 걸까?

답변1

file.txt스크립트나 함수에 첫 번째 인수로 전달된 디렉터리에 파일이 있는지 확인하려면 다음을 사용하세요.

[ -e "$1/file.txt" ]

변수 대체를 큰따옴표로 인용하는 것을 잊지 마세요..

파일이 있으면 성공, 파일이 없으면 실패합니다. 실패에는 파일이 존재하지만 액세스할 수 없는 상황이 포함됩니다. 예를 들어 디렉터리를 탐색할 수 있는 권한이 없기 때문입니다.

쉘 스크립트에서 프로세스 종료 상태와 관련하여 0은 성공을 의미하고 1(또는 그 이상, 최대 125)은 실패를 의미합니다. 바라보다Bash 함수/스크립트에서 어떤 반환/종료 값을 사용할 수 있나요?그리고프로세스 종료 시 기본 종료 코드는 무엇입니까?자세한 내용은. 따라서 파일이 존재하는지 확인하려면 스크립트나 함수는 파일이 존재하면 0을 반환하고 그렇지 않으면 1을 반환해야 합니다. 코드 조각은 반대 작업을 수행합니다. 즉, 파일이 존재하지 않는지 확인합니다.

 if [ -e "$1/file.txt" ]; then
    exit 0
 else
    exit 1
 fi

좀 더 복잡한 글쓰기 방법

[ -e "$1/file.txt" ]
exit

( exit상태 매개변수가 없으면 이전에 실행된 명령의 상태가 사용됩니다.) 이것이 스크립트 끝에 있으면 exit중복됩니다.

!파일이 존재하지 않는지 확인하려면 쉘 연산자를 사용하여 명령을 반대로 할 수 있습니다.

! [ -e "$1/file.txt" ]

또는 ! test/ [연산자:

[ ! -e "$1/file.txt" ]

답변2

[ -e "$1/file.txt" ]

이를 지원하는 쉘/구현에서 [경로 stat()$1/file.txt.

이는 다음과 같습니다:

if ls -Ld -- "$1/file.txt" > /dev/null 2>&1

다음과 동일:

if ls -d -- "$1/file.txt" > /dev/null 2>&1

lstat(), 파일에 대한 작업을 수행할 수 있는 경우 다음과 같습니다.

if [ -e "$1/file.txt" ] || [ -L "$1/file.txt" ]

"깨진" 심볼릭 링크 사례를 재정의합니다( -e심볼릭 링크 해결 후 존재 여부를 테스트할 때 false를 반환함).

이제 실패 stat()lstat()반드시 파일이 존재하지 않는다는 것을 의미하지는 않습니다. / stat()ENOENT lstat()(항목 없음) ENOTDIR(경로 구성 요소가 디렉터리가 아님) 이외의 다른 오류 조건으로 인해 실패할 수 있습니다. 예를 들어 카탈로그 구성 요소에 대한 검색 액세스 권한이 없을 수 있습니다.

이렇게 ls하면 2>&1for를 제거하여 ls오류를 알릴 수 있습니다.그걸로 , 당신 이 할 수 있는 곳을 [사용하지 않으면 알 수 없습니다zsh$ERRNO.

당신이 가지고 있지 않다면찾다디렉토리에 액세스하면 여전히읽다액세스 권한이 있으므로 디렉터리 내용을 읽고 동일한 이름의 파일이 있는지 확인할 수 있습니다.

의 경우 zsh익명 함수를 통해 이 작업을 수행할 수 있습니다 . glob과 일치하는 파일 목록을 전달하는 ()(($#)) $1/file.txt(N)인수( )를 하나 이상 받으면 익명 함수는 glob이 열려 있다는 사실을 반환합니다.()(($#))$1/file.txt(N)(N)NULLGLOB

별도의 문제는 $1/file.txt일부 시스템의 경우와 달라지는 경우입니다.$1///file.txt/file.txt

따라서 디렉토리 에 항목이 있는지 zsh확인하려면 다음 을 사용하십시오 .file.txt$1

exists() {
  local file="${1%/}/file.txt"

  zmodload zsh/system
  local ERRNO=0
  [ -e "$file" ] || [ -L "$file" ] && return 0
  case $errnos[ERRNO] in
    (ENOENT|ENOTDIR) return 1;; # does not exist for sure
    (*) ()(($#)) $file && return 0;;
  esac
  return 2 # meaning: don't know
}

다른 쉘의 경우 다음을 시도해 볼 수 있습니다.

enoent_error=$(
  LC_ALL=C ls -d /surely-does-not-exist 2>&1)
)
enoent_error=${enoent_error##*:}

enotdir_error=$(
  LC_ALL=C ls -d /bin/sh/foo)
)
enotdir_error=${enotdir_error##*:}

exists() (
  file=${1%/}/file.txt
  if error=$(LC_ALL=C ls -d -- "$file" 2>&1 > /dev/null); then
    return 0 # exists for sure
  else
    case $error in
      (*:"$enoent_error"|*:"$enotdir_error")
        return 1;; # does not exist for sure
    esac
  fi
  return 2 # don't know
}

lsC 로케일의 오류 메시지는 다음 패턴을 따른다고 가정합니다 *: fixed error message. fixed error message여기서 각 오류 조건은 다르지만 주어진 오류에 대해 항상 동일하며 다음을 포함하지 않습니다 :(내 시스템에서만 ETOOMANYREFS(참조가 너무 많아 연결할 수 없습니다.) 해당 표준 libc 오류 메시지에 있지만 이는 어쨌든 반환된 errno가 :아닙니다 .lstat()접합할 수 없음다른 오류 메시지에서는 찾을 수 없습니다).


AKA는 [처음에는 test지원되지 않습니다 -e. 먼저 ksh도입되었습니다 -a(그런 다음 단항 및 이항 연산자로 두 배가 됨).접근성나는 그것이 나중에 이름이 바뀌었다고 믿습니다 -e(대부분의 구현에서는 여전히 이를 지원하지만 -a). 이것이 -ePOSIX가 표준 test/ [유틸리티에 대해 지정한 것입니다. /bin/shSolaris 10 및 이전 버전에는 여전히 POSIX가 아닌 Bourne 셸이 있으며 내장 기능은 여전히 ​​Nor 를 [지원하지 않습니다 . 따라서 해당 셸을 사용하려면 다음을 사용 하거나 호출 해야 합니다 . 거기 같은 POSIX 쉘 ) .[ -e[ -als/bin/test/usr/xpg4/bin/sh

관련 정보