PATH 없이 bash 스크립트에서 명령을 실행하는 이식 가능한 방법

PATH 없이 bash 스크립트에서 명령을 실행하는 이식 가능한 방법

cron은 매우 희박한 PATH를 사용하여 내 bash 스크립트(백업 스크립트)를 호출합니다 /usr/bin:/usr. 결과적으로 이런 라인이

lvcreate --size 1G --snapshot ...

터미널에서 스크립트를 실행하면 스크립트가 제대로 작동하지만 crontab에서 실행하면 lvcreate를 찾을 수 없습니다. 비슷한 문제를 설명합니다.여기, 그러나 저는 근본적인 문제를 다루기 위한 일반적인 전략에 더 관심이 있습니다.

지금까지 생각해낸 생각:

  • 빠른 해결 방법으로 스크립트 상단에서 PATH를 수동으로 설정했습니다. crontab에서도 이 작업을 수행할 수 있습니다. 시스템 전체 PATH가 변경되면 이러한 줄을 모두 수동으로 업데이트해야 할 수도 있습니다.

  • 보다 영구적인 해결책은 내 스크립트에서 절대 경로를 사용하는 것입니다. 예를 들어 호출을 /sbin/lvcreate --size 1G ...(RPi) lvcreate가 /usr/bin/에 있는 것으로 바꾸십시오.

  • which각 명령에 대해 PATH를 올바르게 설정하고 결과를 저장하고 스크립트 상단에 로컬 별칭을 설정할 수 있지만 이는 약간 혼란스러운 것 같습니다.

  • 나는 /etc/environment를 소싱하는 것을 고려했습니다. 이것은 내 Ubuntu 컴퓨터에서 작동하지만(일반 데비안에서도 마찬가지라고 생각합니다) 내 RPi에서는 시스템 전체 PATH가 설정되어 있지 않습니다. 나는 같은 이유로 .bashrc 또는 유사한 파일을 사용하는 것을 주저합니다(다양한 배포판에서 특정 파일의 위치 및/또는 사용에 의존하고 싶지 않음).

그래서 내 질문은: 스크립트가 설정된 PATH에 의존하지 않고 여전히 이식성을 유지하도록 만드는 좋은 방법은 무엇입니까? 최첨단 방법이 있나요?

답변1

명시적으로 설정됩니다 PATH.

스크립트에서 이 작업을 수행하는 경우 의 현재 설정에 추가할 수 $PATH있으며 그 안에 있는 모든 내용을 존중하고 잃지 않도록 하고 싶은 것만 추가할 수 있습니다.

#!/bin/bash
PATH=$PATH:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin
...

PATH실제로 cron 자체의 단점을 해결하고 있으므로 crontab 구성에서 설정하는 것이 더 적절할 수 있습니다 (환경 변수를 설정할 수 있는 곳).스크립트를 수정하는 것보다 cron에서 수정하는 것이 더 합리적입니다.

cron에서 설정하는 경우 PATH현재 값을 참조할 수 없으므로 설정을 완료해야 합니다.

# my user's crontab
PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin

0 2 * * * /usr/local/bin/my2amjob.sh

(일부 시스템에 따라 또는 나중에 나열된 디렉토리에 설치된 간단한 버전에 대한 "오버레이"를 설치하는지 여부에 따라 디렉토리 순서가 약간 다를 수 있지만 $PATH시스템의 현재 설정 내용을 확인하여 가능한지 확인하십시오. 화해하세요.)

이것이 귀하의 문제를 해결하기를 바랍니다.

시스템 전체 PATH가 변경되면 이러한 줄을 모두 수동으로 업데이트해야 할 수도 있습니다.

솔직히, 나는 그것에 대해 크게 걱정하지 않을 것입니다. 배포판에는 항상 , /usr/bin또는 아래에 바이너리가 설치되어 있으므로 경로 /usr/sbin를 변경하지 않고도 항상 액세스할 수 있습니다. Distros는 오랫동안 새 디렉터리를 포함하도록 업데이트하는 것을 악몽으로 여겼기 때문에 이를 피하고 대신 홈 디렉터리에 심볼릭 링크나 래퍼 스크립트를 추가했습니다./bin/sbin$PATHbin

업데이트에 권장되는 직접 설치한 소프트웨어의 경우 $PATH아래에서 심볼릭 링크 또는 래퍼 스크립트를 생성하고 /usr/local/bin가능하면 변경을 피하는 것이 좋습니다.$PATH


Linux 배포판도 이러한 차이점을 해결하기 위해 몇 가지 조치를 취하고 있습니다 $PATH.

가장 먼저/usr노력 통합, 그것은 /bin심볼릭 링크 가 /usr/bin되고 /sbin심볼릭 링크가 됩니다 /usr/sbin. 모든 바이너리는 /usr(패키저가 더 쉽게) 설치되지만 스크립트는 여전히 일부 절대 경로를 통해 이를 참조 /bin/mytool하거나 /sbin/mytool심볼릭 링크를 통해 계속 작동합니다. 이는 Fedora, ArchLinux 등의 배포판에서 이미 채택되었으며, Debian, Ubuntu 등의 다른 배포판에서도 현재 채택 단계를 거치고 있습니다.

ArchLinux는 한 단계 더 나아간 것 같습니다.sbin함께 병합bin. 따라서 통합 기능이 있는 최신 ArchLinux에서는 가능한 네 가지 절대 경로 중 하나로 바이너리를 참조할 수 있으며 찾을 수 있습니다. 다른 배포판에서도 두 번째 병합을 채택할지 여부는 아직 알 수 없습니다.


마지막으로 cron에 대한 보다 현대적인 대안을 고려할 수도 있습니다. Cron은 여러분이 경험하고 있는 노출된 환경과 같은 많은 기능을 가지고 있지만 (로깅 시스템을 사용하는 대신) 명령 출력을 위해 이메일을 사용하고 어색한 명령줄 이스케이프도 사용합니다.

패키지를 설치하지 않고도 내장된 시스템 타이머를 지원하는 Ubuntu와 ArchLinux를 언급하셨습니다.

사용 방법에 대한 훌륭한 기사가 있는 ArchLinux 위키를 확인해 보세요. 특히 다음 사항을 확인하고 싶을 수도 있습니다.cron 교체로 systemd 타이머 사용에는 특정 사용 사례에 유용할 수 있는 특정 레시피가 있습니다.

관련 정보