에서 man bash
:
CONDITIONAL EXPRESSIONS
[...]
-a file
True if file exists.
[...]
-e file
True if file exists.
[ -a $FILE ]
[ -e $FILE ]
그렇다면 의 차이점은 무엇 입니까 ?- 실제 차이가 없다면 동일한 목적을 위해 두 개의 플래그가 존재하는 이유는 무엇입니까?
답변1
bash
두 개의 인수가 있는 명령의 맥락 에서 test
, -a file
및 -e file
은 동일합니다. 그러나 -a
이항 연산자이기도 하기 때문에 약간의 차이점이 있습니다 .
-e
단항은 POSIX에 의해 정의되지만 -a
단항은 그렇지 않습니다. POSIX는 바이너리만 정의합니다 -a
(참조:시험POSIX).
POSIX는 세 가지 매개변수 test
동작을 정의합니다.
3개 매개변수:
$2가 기본 바이너리인 경우 $1과 $3에 대해 바이너리 테스트를 수행합니다.
$1이 '!'인 경우 $2와 $3의 두 인수 테스트를 무효화합니다.
$1이 "("이고 $3이 ")"인 경우 $2의 단항 테스트를 수행합니다. XSI 옵션을 지원하지 않는 시스템에서 $1이 "("이고 $3이 ")"인 경우 결과는 지정되지 않습니다.
그렇지 않으면 지정되지 않은 결과가 생성됩니다.
따라서 -a
이상한 결과도 발생합니다.
$ [ ! -a . ] && echo true
true
-a
세 인수의 맥락에서 이항 연산자로 처리됩니다. 바라보다배쉬 FAQ 문제 E1. POSIX에서는 KornShell에서 가져오는 것에 대해서도 언급했지만 바이너리와 단항을 혼동했기 때문에 -a
나중에 변경되었습니다 .-e
-a
-a
기본 -e를 추가하면 파일을 열려고 하지 않고 파일이 존재하는지 여부를 알아내는 쉘 스크립트에 대한 유일한 방법을 제공한다는 점에서 C 쉘에서 제공하는 것과 유사한 기능을 갖습니다. 구현 시 추가 파일 형식을 추가할 수 있으므로 이식 가능한 스크립트를 사용할 수 없습니다.
테스트 -b foo -o -c foo -o -d foo -o -f foo -o -p foo
foo가 기존 파일인지 확인합니다. 과거 BSD 시스템에서 파일의 존재는 다음을 통해 확인할 수 있습니다.
테스트 -f foo -o -d foo
그러나 기존 파일이 일반 파일인지 쉽게 확인할 수 있는 방법은 없습니다. 초기 제안에서는 KornShell -a 기본 연산자(동일한 의미를 가짐)를 사용했지만 사람들이 -a 기본 연산자와 -a 이진 연산자를 혼동할 수 있다는 우려 때문에 나중에 -e로 변경했습니다.
-a
또한 바이너리는 4개 이상의 인수가 포함된 일부 모호한 표현식이 생성되므로 더 이상 사용되지 않는 것으로 표시됩니다. 이러한 4개 이상의 인수 표현식의 경우 POSIX는 결과를 지정되지 않도록 정의합니다.
답변2
.1.그러면 [ -a $FILE ]과 [ -e $FILE ]의 차이점은 무엇입니까?
전혀 차이가 없습니다.
배쉬 버전에서 505-507
:test.c
4.2.45(1)-release
case 'a': /* file exists in the file system? */
case 'e':
return (sh_stat (arg, &stat_buf) == 0);
이는 두 플래그 사이에 실제 차이가 없음을 보여줍니다.
.2. 실제 차이가 없다면 동일한 목적으로 두 개의 플래그가 존재하는 이유는 무엇입니까?
바라보다cuonglm의 답변.
답변3
내가 찾은 가장 좋은 대답은 StackOverflow에 대한 질문에서 나온 것입니다.
-a
더 이상 사용되지 않으므로 더 이상 맨페이지에 나열되지 않지만/usr/bin/test
bash 맨페이지에는 계속 나열됩니다. 사용-e
. 단일 "["의 경우 bash 내장 기능은 bash 내장 기능과 동일하게 작동하며 이는test
and와 동일하게 작동합니다(하나는 다른 하나에 대한 심볼릭 링크입니다). 효과는 위치에 따라 달라집니다. 시작 부분에 있으면 의미합니다. 두 표현식의 중간에 있으면 논리를 나타냅니다./usr/bin/[
/usr/bin/test
-a
file exists
and
[ ! -a /path ] && echo exists
bash 매뉴얼에서 지적했듯이 작동하지 않습니다.-a
이항 연산자로 간주되므로 위의 내용은 a로 구문 분석되지 않고negate -a ..
(if '!' and '/path' is true
null이 아닌)로 구문 분석됩니다. 따라서 스크립트는 항상 출력"-a"
(실제로는 테스트 파일)하며 여기서는"! -a"
실제로 바이너리 파일입니다and
.for 는
[[
더-a
이상 바이너리로 사용되지 않으므로and
(&&
더 이상 사용되지 않지만) 고유한 목적은 거기에서 파일을 확인하는 것입니다. 따라서 부정은 실제로 예상한 대로 작동합니다.