![변수에 저장된 공백으로 구분된 인수를 명령에 전달합니다.](https://linux55.com/image/145259/%EB%B3%80%EC%88%98%EC%97%90%20%EC%A0%80%EC%9E%A5%EB%90%9C%20%EA%B3%B5%EB%B0%B1%EC%9C%BC%EB%A1%9C%20%EA%B5%AC%EB%B6%84%EB%90%9C%20%EC%9D%B8%EC%88%98%EB%A5%BC%20%EB%AA%85%EB%A0%B9%EC%97%90%20%EC%A0%84%EB%8B%AC%ED%95%A9%EB%8B%88%EB%8B%A4..png)
인터넷에서 아주 깔끔한 백업 스크립트를 하이재킹했는데, 어딘가에서 이런 일이 일어났습니다.
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에서는 모든 대문자 변수를 피하는 것이 가장 좋다고 덧붙이고 싶었습니다. 관례적으로 환경 변수와 내부 쉘 변수는 대문자로 표시됩니다. 중요한 내용을 덮어쓰지 않도록 다른 모든 변수 이름은 소문자로 유지하는 것이 가장 좋습니다.