쉘 스크립트에 파일이 있는지 확인하는 방법


175

특정 파일 ()이 있는지 확인 archived_sensor_data.json하고 있으면 삭제 하는 쉘 스크립트를 작성하고 싶습니다 . http://www.cyberciti.biz/tips/find-out-if-file-exists-with-conditional-expressions.html 에 따라 다음을 시도했습니다.

[-e archived_sensor_data.json] && rm archived_sensor_data.json

그러나 이것은 오류가 발생합니다

[-e: command not found

명령을 test_controller사용하여 결과 스크립트 를 실행하려고 할 때 ./test_controller. 코드에 어떤 문제가 있습니까?



2
여는 대괄호 "["와 옵션 "-e"사이에 하나 이상의 공백을 파일 이름과 닫는 대괄호 "]"사이에 동일하게 설정해야합니다.
Konstantin Yaniv

답변:


350

대괄호와 -e: 사이에 필요한 공간이 없습니다 .

#!/bin/bash
if [ -e x.txt ]
then
    echo "ok"
else
    echo "nok"
fi

12
마지막으로 두 개의 빈 공간을 추가했습니다. 하나는 여는 대괄호 다음과 다른 하나는 닫는 공백 앞에 추가했습니다 [ -e archived_sensor_data.json ] && rm archived_sensor_data.json. 스크립트가 지금 작동하는 것 같습니다.
커트 픽

3
if [ -e "$1" ](filename 입력 인수)를 사용하여 작동합니다 .
에드워드

2
여기서 가장 큰 차이점은 "쉘"스크립팅 대신 "bash"스크립팅을 사용한다는 사실입니다. 추가 한 첫 번째 줄은 #! / bin / bash이므로, sh 대신 "bash"를 사용하도록 시스템에 지시합니다. sh는 그 주장 "-e"를 인식하지 못하기 때문에
Nick Cuevas

29

다음을 사용하는 대체 방법이 있습니다 ls.

(ls x.txt && echo yes) || echo no

당신의 모든 출력 숨기려면 ls당신은 예 또는 아니오 볼 수 있도록를, 리디렉션 stdoutstderr/dev/null:

(ls x.txt >> /dev/null 2>&1 && echo yes) || echo no

1
이 코드는 " ls성공한 경우 해당 파일이 있고 그렇지 않은 경우 없음"을 의미합니다. 경우 ls에 실패, 그 파일이없는 것을 의미하지 않는다. 다른 오류 일 수 있습니다. 예를 들어, 루트가 소유 한 디렉토리에 파일을 작성하고 ls일반 사용자로 시도하십시오 . Permission denied파일이 존재하지 않는 것과 동일하지 않은로 실패 합니다.
Tigran

9

내 솔루션 권장 사항의 배경은 첫 번째 작업의 두 번째 주에 빌드 서버 청소의 절반을 닦은 친구의 이야기입니다. 기본 작업은 파일이 존재하는지 확인하고 존재하는 경우 삭제하는 것입니다. 그러나이 강에는 몇 가지 위험한 급류가 있습니다.

  • 모든 것이 파일입니다.

  • 스크립트는 일반적인 작업을 해결할 때만 강력한 힘을 발휘합니다

  • 일반적으로 변수를 사용합니다

  • 우리는 종종 수동 개입을 피하기 위해 스크립트에서 -f force를 사용합니다.

  • 또한 적시에 우리가 만들고, 복사하고, 파괴 할 수 있도록 재귀를 사랑합니다.

다음 시나리오를 고려하십시오.

삭제하려는 파일이 있습니다 : filesexists.json

이 파일 이름은 변수에 저장됩니다

<host>:~/Documents/thisfolderexists filevariable="filesexists.json"

우리는 또한 일을 정말 유연하게하기 위해 경로 변수를 가지고 있습니다

<host>:~/Documents/thisfolderexists pathtofile=".."

<host>:~/Documents/thisfolderexists ls $pathtofile

filesexists.json  history20170728  SE-Data-API.pem  thisfolderexists

따라서 -e예상대로 작동하는지 봅시다 . 파일이 존재합니까?

<host>:~/Documents/thisfolderexists [ -e $pathtofile/$filevariable ]; echo $?

0

그렇습니다. 마법.

그러나 파일 변수가 실수로 nuffin으로 평가되면 어떻게 될까요?

<host>:~/Documents/thisfolderexists filevariable=""

<host>:~/Documents/thisfolderexists [ -e $pathtofile/$filevariable ]; echo $?

0

뭐? 그것은 오류와 함께 반환되어야합니다 ... 그리고 이것은 우연히 전체 폴더가 삭제 된 이야기의 시작입니다.

대안은 우리가 '파일'로 이해하는 것을 구체적으로 테스트하는 것일 수 있습니다.

<host>:~/Documents/thisfolderexists filevariable="filesexists.json"

<host>:~/Documents/thisfolderexists test -f $pathtofile/$filevariable; echo $?

0

그래서 파일이 존재합니다 ...

<host>:~/Documents/thisfolderexists filevariable=""

<host>:~/Documents/thisfolderexists test -f $pathtofile/$filevariable; echo $?

1

그래서 이것은 파일이 아니며 아마도 전체 디렉토리를 삭제하고 싶지 않을 것입니다

man test 다음과 같이 말합니다.

-b FILE

       FILE exists and is block special

-c FILE

       FILE exists and is character special

-d FILE

       FILE exists and is a directory

-e FILE

       FILE exists

-f FILE

       FILE exists and is a regular file

...

-h FILE

       FILE exists and is a symbolic link (same as -L)

4

내부적으로 rm 명령은 파일 존재를 테스트해야하는데
왜 다른 테스트를 추가해야합니까? 그냥 발행

rm filename

그것이 있든 없든 그 후에 사라질 것입니다.
rm -f를 사용하면 존재하지 않는 파일에 대한 메시지를 원하지 않습니다.

파일이 존재하지 않는 경우 조치를 취해야하는 경우 직접 테스트해야합니다. 예제 코드를 기준으로이 경우에는 그렇지 않습니다.


1
이것은 실제로 rm 명령에 대한 올바른 대답입니다. 다른 명령의 경우 -e로 테스트하는 것이 좋습니다.
warhansen

그것을 제외하고는 질문이 요구하는 것이 아닙니다.
크레용 2

1
"... 그리고 (있는 경우) ... 삭제"부분을 포함하여 전체 질문 을 읽으면 질문이 묻는 것입니다.
TG

1

NFS를 사용하는 경우 "테스트"가 더 나은 솔루션입니다. NFS가 다운 된 경우 시간 초과를 추가 할 수 있기 때문입니다.

time timeout 3 test -f 
/nfs/my_nfs_is_currently_down
real    0m3.004s <<== timeout is taken into account
user    0m0.001s
sys     0m0.004s
echo $?
124   <= 124 means the timeout has been reached

"[-e my_file]"구문은 NFS가 다시 작동 할 때까지 정지됩니다.

if [ -e /nfs/my_nfs_is_currently_down ]; then echo "ok" else echo "ko" ; fi

<no answer from the system, my session is "frozen">

test그리고 [동의어입니다. 당신은 사용할 수 timeout와 함께 [뿐만 아니라, 그리고 test또한 NFS가 정지하면 정지.
다른 사람
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.