변수에 저장된 공백으로 구분된 인수를 명령에 전달합니다.

변수에 저장된 공백으로 구분된 인수를 명령에 전달합니다.

인터넷에서 아주 깔끔한 백업 스크립트를 하이재킹했는데, 어딘가에서 이런 일이 일어났습니다.

DIRS="/home/ /var/www/html /etc"

tar -czf /backup/file.tar.gz "${DIRS}"

이것은 내 컴퓨터에서는 잘 작동하지만 내 서버에서는 이 경로가 단일 경로라고 생각하고 경로가 존재하지 않는다고 알려줍니다.

/bin/tar: /home/ /var/www/html /etc: Cannot stat: No such file or directory 
/bin/tar: Exiting with failure status due to previous errors

로컬 tar 버전은 1.29이고 서버 버전은 1.28입니다.

이 변수와 별도의 디렉토리를 tar에 제공하는 올바른 방법은 무엇입니까?

답변1

이것이 bash 스크립트(또는 대부분의 sh 버전)인 한 변수 대신 매개변수를 전달하려면 배열을 사용해야 합니다.

DIRS=('/home/' '/var/www/html' '/etc')

tar -czf /backup/file.tar.gz "${DIRS[@]}"

원하는 경우 다음과 같이 작성할 수 있습니다(일반적으로 배열이 커지면 읽기가 더 쉽습니다).

DIRS=(
    '/home/' 
    '/var/www/html' 
    '/etc'
)

배열을 지원하지 않는 셸에서는 단어 분리를 허용하도록 변수를 역참조해야 합니다(피할 수 있는 경우 권장하지 않음):

DIRS="/home/ /var/www/html /etc"

tar -czf /backup/file.tar.gz $DIRS

변수를 참조하여 이러한 인수를 전달하는 경우 기본적으로 다음과 같습니다.

tar -czf /backup/file.tar.gz "/home/ /var/www/html /etc"

그러나 인용된 배열을 통해 전달하면 다음과 같이 됩니다.

tar -czf /backup/file.tar.gz "/home/" "/var/www/html" "/etc"

따옴표가 없는 배열이나 변수를 통해 전달하면 다음과 유사한 작업이 수행됩니다.

tar -czf /backup/file.tar.gz /home/ /var/www/html /etc

이 예에서는 문제가 되지 않지만 추가 단어 분리기 및 바람직하지 않거나 잠재적으로 해로울 수 있는 기타 유형의 확장이 발생합니다.

답변2

jesse_b의 의견에 동의합니다. 가능하다면 배열을 사용하세요.

dirs="/home/ /var/www/html /etc"
dirs=($dirs)
tar -czf /backup/file.tar.gz "${dirs[@]}"

bash에서는 모든 대문자 변수를 피하는 것이 가장 좋다고 덧붙이고 싶었습니다. 관례적으로 환경 변수와 내부 쉘 변수는 대문자로 표시됩니다. 중요한 내용을 덮어쓰지 않도록 다른 모든 변수 이름은 소문자로 유지하는 것이 가장 좋습니다.

관련 정보