안녕하세요, 저는 디렉터리 경로를 매개변수로 사용하고 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>&1
for를 제거하여 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
}
ls
C 로케일의 오류 메시지는 다음 패턴을 따른다고 가정합니다 *: fixed error message
. fixed error message
여기서 각 오류 조건은 다르지만 주어진 오류에 대해 항상 동일하며 다음을 포함하지 않습니다 :
(내 시스템에서만 ETOOMANYREFS
(참조가 너무 많아 연결할 수 없습니다.) 해당 표준 libc 오류 메시지에 있지만 이는 어쨌든 반환된 errno가 :
아닙니다 .lstat()
접합할 수 없음다른 오류 메시지에서는 찾을 수 없습니다).
AKA는 [
처음에는 test
지원되지 않습니다 -e
. 먼저 ksh
도입되었습니다 -a
(그런 다음 단항 및 이항 연산자로 두 배가 됨).접근성나는 그것이 나중에 이름이 바뀌었다고 믿습니다 -e
(대부분의 구현에서는 여전히 이를 지원하지만 -a
). 이것이 -e
POSIX가 표준 test
/ [
유틸리티에 대해 지정한 것입니다. /bin/sh
Solaris 10 및 이전 버전에는 여전히 POSIX가 아닌 Bourne 셸이 있으며 내장 기능은 여전히 Nor 를 [
지원하지 않습니다 . 따라서 해당 셸을 사용하려면 다음을 사용 하거나 호출 해야 합니다 . 거기 같은 POSIX 쉘 ) .[ -e
[ -a
ls
/bin/test
/usr/xpg4/bin/sh