웹사이트 검색

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


Linux Bash 스크립트가 존재하는 특정 파일이나 디렉토리에 의존하는 경우 그렇다고 가정할 수는 없습니다. 그들이 확실히 존재하는지 확인해야합니다. 방법은 다음과 같습니다.

아무것도 가정하지 마십시오

스크립트를 작성할 때 컴퓨터에 있는 것과 없는 것에 대해 가정할 수 없습니다. 스크립트가 여러 다른 컴퓨터에서 배포되고 실행될 예정이라면 이는 두 배로 사실입니다. 조만간 스크립트는 귀하의 가정을 충족하지 않는 컴퓨터에서 실행될 것이며 스크립트는 실패하거나 예측할 수 없게 실행될 것입니다.

우리가 컴퓨터에서 중요하게 여기거나 생성하는 모든 것은 특정 형식의 파일에 저장되며 이러한 모든 파일은 디렉토리에 있습니다. 스크립트는 파일과 디렉터리를 읽고, 쓰고, 이름을 바꾸고, 삭제하고, 이동할 수 있습니다. 명령줄에서 수행할 수 있는 모든 작업을 수행할 수 있습니다.

인간으로서 얻을 수 있는 이점은 디렉토리의 내용을 볼 수 있고 파일이 존재하는지 여부 또는 예상 디렉토리가 존재하는지 여부를 알 수 있다는 것입니다. 파일을 조작할 때 스크립트가 잘못되면 심각하고 해로운 결과를 초래할 수 있습니다.

Bash는 파일 및 디렉토리를 감지하고 많은 속성을 테스트하는 데 사용할 수 있는 포괄적인 테스트 세트를 제공합니다. 이를 스크립트에 통합하는 것은 쉽지만 견고성과 미세 제어 측면에서 상당한 이점이 있습니다.

테스트 범위

if 문을 대규모 파일 및 디렉터리 테스트 모음의 적절한 테스트와 결합하면 파일이 존재하는지, 실행 가능한지 또는 쓰기 가능한지 등을 쉽게 확인할 수 있습니다.

  • -b: 파일이 블록 특수 파일인 경우 true를 반환합니다.
  • -c: 파일이 특수 문자인 경우 true를 반환합니다.
  • -d: 파일이 디렉토리인 경우 true를 반환합니다.
  • -e: 파일이 존재하는 경우 true를 반환합니다.
  • -f: 파일이 존재하고 일반 파일이면 true를 반환합니다.
  • -g: 파일에 setgid 권한 집합(chmod g+)이 있는 경우 true를 반환합니다.
  • -h: 파일이 심볼릭 링크인 경우 true를 반환합니다.
  • -L: 파일이 심볼릭 링크인 경우 true를 반환합니다.
  • -k: 고정 비트가 설정되어 있으면 true를 반환합니다(chmod +t).
  • -p: 파일이 명명된 파이프인 경우 true를 반환합니다.
  • -r: 파일을 읽을 수 있으면 true를 반환합니다.
  • -s: 파일이 존재하고 비어 있지 않은 경우 true를 반환합니다.
  • -S: 파일이 소켓이면 true를 반환합니다.
  • -t: 파일 디스크립터가 터미널에서 열리면 true를 반환합니다.
  • -u: 파일에 setuid 권한 집합(chmod u+)이 있으면 true를 반환합니다.
  • -w: 파일이 쓰기 가능한 경우 true를 반환합니다.
  • -x: 파일이 실행 가능한 경우 true를 반환합니다.
  • -O: 이 소유하고 있는 경우 true를 반환합니다.
  • -G: 그룹 소유인 경우 true를 반환합니다.
  • -N: 마지막으로 읽은 이후 파일이 수정된 경우 true를 반환합니다.
  • !: 논리 NOT 연산자입니다.
  • &&: 논리 AND 연산자입니다.
  • ||: 논리적 OR 연산자입니다.

목록은 -a 테스트가 더 이상 사용되지 않고 -e 테스트로 대체되었기 때문에 -b로 시작합니다.

스크립트에서 테스트 사용

일반 파일 테스트 if 문은 간단한 스크립팅 구조입니다. 이중 괄호 ” [[ ]] ” 안의 비교는 -f 테스트를 사용하여 해당 이름을 가진 일반 파일이 존재하는지 확인합니다.

이 스크립트의 텍스트를 편집기에 복사하고 script1.sh라는 파일에 저장하고 chmod를 사용하여 실행 가능하게 만듭니다.

#!/bin/bash

if [[ -f $1 ]] 

then 

  echo "The file $1 exists." 

else 

  echo "The file $1 cannot be found." 

fi

명령줄의 스크립트에 파일 이름을 전달해야 합니다.

chmod +x script1.sh

기사의 다른 예제를 시도하려면 각 스크립트에서 이 작업을 수행해야 합니다.

간단한 텍스트 파일에서 스크립트를 사용해 봅시다.

./script1.sh test-file.txt

파일이 존재하고 스크립트가 해당 사실을 올바르게 보고합니다. 파일을 삭제하고 다시 시도하면 테스트가 실패하고 스크립트가 이를 보고해야 합니다.

./script1.sh test-file.txt

실제 상황에서 스크립트는 적절한 조치를 취해야 합니다. 아마도 오류에 플래그를 지정하고 중지합니다. 아마도 파일을 생성하고 계속할 것입니다. 누락된 파일을 대체하기 위해 백업 디렉토리에서 무언가를 복사할 수 있습니다. 그것은 모두 스크립트의 목적에 달려 있습니다. 그러나 적어도 이제 스크립트는 파일이 있는지 여부를 아는 것을 기반으로 결정을 내릴 수 있습니다.

-f 플래그는 파일이 존재하고 일반 파일인지 여부를 테스트합니다. 즉, 장치 파일과 같이 파일인 것처럼 보이지만 파일이 아닌 것이 아닙니다.

ls를 사용하여 /dev/random 파일이 존재하는지 확인한 다음 스크립트가 무엇을 만드는지 확인합니다.

ls -lh /dev/random
./script /dev/random

스크립트가 일반 파일에 대해 테스트 중이고 /dev/random이 장치 파일이기 때문에 테스트가 실패합니다. 매우 자주 파일이 존재하는지 여부를 확인하려면 사용할 테스트를 신중하게 선택하거나 여러 테스트를 사용해야 합니다.

이것은 일반 파일과 문자 장치 파일을 테스트하는 “script2.sh”입니다.

#!/bin/bash

if [[ -f $1 ]]
then
  echo "The file $1 exists."
else
  echo "The file $1 is missing or not a regular file."
fi

if [[ -c $1 ]]
then
  echo "The file $1 is a character device file."
else
  echo "The file $1 is missing or not a special file." 
fi

/dev/random 장치 파일에서 이 스크립트를 실행하면 첫 번째 테스트는 예상대로 실패하고 두 번째 테스트는 성공합니다. 파일을 장치 파일로 인식합니다.

./script2.sh /dev/random

실제로 캐릭터 기기 파일로 인식합니다. 일부 장치 파일은 블록 장치 파일입니다. 그대로, 우리의 스크립트는 그것들에 대처하지 못할 것입니다.

./script2.sh /dev/sda

논리적 OR 연산자를 사용하고 두 번째 if 문에 다른 테스트를 포함할 수 있습니다. 이번에는 파일이 캐릭터 장치 파일이든 이든 블록 장치 파일이든 관계없이 테스트에서 true를 반환합니다. 이것은 script3.sh입니다.

#!/bin/bash

if [[ -f $1 ]]
then
  echo "The file $1 exists."
else
  echo "The file $1 is missing or not a regular file."
fi

if [[ -c $1 || -b $1 ]]
then
  echo "The file $1 is a character or block device file."
else
  echo "The file $1 is missing or not a special file." 
fi

이 스크립트는 문자 장치와 블록 장치 파일을 모두 인식합니다.

./script3.sh /dev/random
./script3.sh /dev/sda

서로 다른 유형의 장치 파일을 구분하는 것이 중요한 경우 중첩된 if 문을 사용할 수 있습니다. 이것은 script4.sh입니다.

#!/bin/bash

if [[ -f $1 ]]
then
  echo "The file $1 exists."
else
  echo "The file $1 is missing or not a regular file."
fi

if [[ -c $1 ]]
then
  echo "The file $1 is a character device file."
else
  if [[ -b $1 ]]
  then
    echo "The file $1 is a block device file." 
  else
    echo "The file $1 is missing or not a device file."
  fi
fi

이 스크립트는 문자 장치와 블록 장치 파일을 모두 인식하고 분류합니다.

./script4.sh /dev/random
./script4.sh /dev/sda

논리 AND 연산자를 사용하여 한 번에 여러 특성을 테스트할 수 있습니다. 이것은 script5.sh입니다. 파일이 있는지 확인하고 스크립트에 읽기 쓰기 권한이 있는지 확인합니다.

#!/bin/bash

if [[ -f $1 && -r $1 && -w $1 ]]
then
  echo "The file $1 exists and we have read/write permissions."
else
  echo "The file $1 is missing, not a regular file, or we can't read/write to it."
fi

우리는 우리에게 속한 파일과 root에 속한 파일에서 스크립트를 실행할 것입니다.

./script5.sh .bashrc
./script5.sh /etc/fstab

디렉토리의 존재를 테스트하려면 -d 테스트를 사용하십시오. 이것은 script6.sh입니다. 백업 스크립트의 일부입니다. 가장 먼저 하는 일은 명령줄에 전달된 디렉토리가 존재하는지 여부를 확인하는 것입니다. if 문 테스트에서 논리 NOT 연산자 !를 사용합니다.

#!/bin/bash

if [[ ! -d $1 ]]
then
  echo "Creating backup directory:" $1
  mkdir $1

  if [[ ! $? -eq 0 ]]
  then
    echo "Couldn't create backup directory:" $1
    exit
  fi
else
  echo "Backup directory exists."
fi

# continue with file backup
echo "Backing up to: "$1

디렉토리가 존재하지 않으면 생성합니다. 디렉토리 생성 파일이 있으면 스크립트가 종료됩니다. 디렉터리 생성에 성공하거나 디렉터리가 이미 존재하는 경우 스크립트는 백업 작업을 계속합니다.

스크립트를 실행한 다음 ls-d(디렉토리) 옵션을 사용하여 백업 디렉토리가 있는지 확인합니다.

./script6.sh Documents/project-backup
ls -d Documents/project-backup

백업 디렉토리가 생성되었습니다. 스크립트를 다시 실행하면 디렉토리가 이미 존재한다고 보고해야 합니다.

./script6.sh

스크립트는 디렉터리를 찾고 백업을 수행하기 위해 이동합니다.

테스트하고 가정하지 마십시오

조만간 잘못된 가정으로 인해 나쁜 일이 발생할 것입니다. 먼저 테스트하고 그에 따라 반응하십시오.

아는 것이 힘이다. 테스트를 사용하여 스크립트에 필요한 지식을 제공하십시오.