형식 고려사항
질문에서 세부 사항이 사라진 것 같아서 돌아가서 특정 질문에 굵은 텍스트를 추가했습니다. 그러나 가장 간단한 솔루션이 반드시 작동하지 않는 이유를 이해하려면 세부 사항이 필요합니다.
배경
최근 StackOverflow에서 이와 같은 질문이 제기되었는데, 엄격한 의미에서 프로그래밍과 관련이 없기 때문에 친절하게 받아들이지 않았습니다. 우리 회사는 클라우드로 대대적인 전환을 진행하고 있으며 모든 것을 로컬에서 구축하는 대신 Docker를 사용하고 있습니다. 전반적으로 훌륭하지만 우리는 옳은 일을 하려고 노력하고 있습니다™. 이를 달성하기 위해 나는 Unix/Linux의 깊이와 그것이 어떻게 작동하는지에 대해 많은 것을 배웠지만, 어떤 접근 방식이 다른 접근 방식보다 더 나은지 반드시 이해하지는 못했습니다.
편집하다
Marcus가 제공한 풍부한 정보 후에 저는 더 많은 맥락을 추가해야 한다는 것을 깨달았습니다. 따라서 우리는 GitLab CI/CD를 사용하여 클라우드에 코드를 배포합니다. 우리는 높은 보안 요구 사항을 갖고 있고 누군가가 보안 스캔이나 그러한 성격의 기타 작업을 건너뛰는 것을 허용할 수 없기 때문에 파이프라인 설계는 개별 리포지토리에 맡겨지지 않습니다. 이러한 수준의 제어를 제공하기 위해 파이프라인을 외부 저장소로 만들고, 여기에는 다른 파이프라인 프로젝트에 의해 연결될 수 있는 확장 지점이 있습니다(메인 파이프라인으로 승격된 병합 요청을 통해).
파이프라인 확장은 YAML 구성과 Docker 이미지라는 두 부분으로 구성됩니다. YAML을 짧게 유지하기 위해 우리는 특정 파이프라인 단계에 대한 모든 논리를 그것이 실행되는 컨테이너에 넣는 접근 방식을 취했습니다. 이 작업을 수행하는 초기에는 많은 스크립트가 /usr/local/bin
.
docker compose up
timeout $SERVICE_READY_TIMEOUT sh -c \
"until curl --output /dev/null --silent --fail $SERVICE_READY_ENDPOINT; do \
sleep 1; \
done"
# run the integration test after service is ready
대신 다음과 같은 스크립트를 추가했습니다 /etc/profile.d
.
#!/bin/sh
## Define functions to be loaded into the shell environment
pollUrl() {
endpoint="$1"
until curl --output /dev/null --silent --fail "$endpoint"; do
sleep 1;
done
}
waitForLive() {
max_duration=$1
endpoint="$2"
timeout $max_duration sh -c "pollUrl '$endpoint'"
}
제가 해결하려는 또 다른 구체적인 문제는 다른 단계에서 사용하기 위해 한 단계에 환경 변수를 저장하는 것입니다. 예, 가장 쉬운 해결책은 두 위치 모두에 복사하는 것입니다. 문제는 두 가지 버전이 있다는 것입니다. 제가 캡처하는 변수는 Docker 이미지 빌드에 제공되지만 나중에 실제 파이프라인 확장에 사용됩니다. 나의 현재 접근 방식 /etc/profile.d
에도 그것을 적어 두었습니다.
그러나 우리는 원래의 질문으로 돌아갑니다.ENV
프로필이 로드되도록 사용자에 대해 이를 어떻게 정의합니까?
질문
쉘이 시작될 때 어떤 일이 발생하는지, 언제가 /etc/init.d
선호되는지, 언제와 비교하여 올바른 구성 파일이 처음에 로드되도록 /etc/profile.d
정의하려면 어떻게 해야 합니까 ? $ENV
더 중요한 것은 어떤 유형의 물건이 어디로 가는가입니다.예: 재사용을 위해 셸에 로드할 함수, NPM/Yarn과 같은 도구를 구성하는 데 사용되는 환경 변수, 특히 $ENV
셸 시작 방법을 결정하는 요소.
나는 전체적으로 Linux를 처음 접했기 때문에 이러한 사항을 설명하는 공식 문서가 있다면 매우 도움이 될 것입니다. 나는 Linux Documentation Project(PDF)를 다운로드했고 거기에 있는 다양한 Linux 매뉴얼 페이지 사이트를 자주 방문했지만 대부분의 소스는 Bash를 선호하지만 이는 항상 나에게 선택 사항은 아닙니다.
업데이트된 질문
그래서 제가 이런 질문을 하는 것입니다.관련 쉘(Bash, ZSH 등)에 특정되지 않은 쉘에서 함수 및 환경 변수를 정의하는 POSIX 호환 방법은 무엇입니까? 한 시스템과 다른 시스템에서 언제 사용해야 하는지에 대해 어떤 지침을 제공할 수 있나요?
추가 정보
.<name>rc
ZSH 및 Bash와 같은 일부 쉘은 실행 명령 파일 뿐만 아니라 .<name>_profile
또는 와 같은 다른 규칙도 제공한다는 것을 알고 있습니다 .profile
. 이를 통해 ENV=/etc/profile
Dockerfile의 설정은 현재 사용자로 /etc/profile.d
끝나고 현재 사용자가 실행할 수 *.sh
있는 디렉터리의 모든 항목을 로드한다는 것을 이해하게 되었습니다 . 그러나 원하는 대로 사용자 정의할 수 있는 WSL 환경에서는 ENV
셸에 들어가기 전에 값을 미리 로드 할 수 없습니다 . 특히 /bin/sh
크로스 플랫폼 스크립팅 호환성을 테스트하기 위해 값을 사용하려고 할 때(Mac 사용자가 있으므로 내 Bash 스크립트는 종종 충돌이 발생합니다.
답변1
쉘을 시작할 때 어떤 일이 발생하는지, 언제 /etc/init.d가 선호되고 언제 /etc/profile.d가 선호됩니까?
그들은 완전히 다른 일을 합니다.
profile.d에는 공용 환경을 설정하는 데 사용되는 셸에서 가져온 스크립트가 포함되어 있습니다. init.d에는 부팅 제어 프로그램에서 시작하여 서비스 구성을 시작, 중지, 다시 시작 또는 다시 로드하는 스크립트가 포함되어 있습니다. 이 스크립트에 전달된 매개변수에 대해
회사가 현재 클라우드로 전환하는 경우 일반적인 클라우드 VM 배포(OpenSUSE, Alma Linux/Rocky Linux/Oracle Linux/Red Hat Enterprise Linux 또는 Ubuntu)가 이를 수행합니다.아니요SysV를 사용하세요. (에뮬레이션 레이어를 통해 지원합니다.)
이러한 배포판은 실제로 systemd의 세분화된 제어, 병렬성 및 탄력성 기능을 활용합니다.
다른 일반적인 클라우드 배포는 컨테이너에서 단일 서비스를 시작하는 것을 기반으로 하므로 일반적으로반품이러한 컨테이너에는 sysvinit에 대한 종속성이 없습니다.
따라서 진짜 질문은 클라우드 서비스를 고려할 때 왜 2024년에 sysvinit를 읽을 것인가입니다.
예: 재사용을 위해 셸에 로드할 함수, NPM/Yarn과 같은 도구를 구성하는 데 사용되는 환경 변수, 특히 셸 시작 방법을 결정하는 $ENV와 같은 항목.
이는 개발/사용 문제이며 클라우드 서버에서 수행하고 싶은 작업처럼 들리지 않습니다. 일반적으로 특정 서비스를 실행하는 데 필요한 환경 변수를 서비스 파일에 배치합니다(systemd의 경우). sys v 초기화 스크립트의 경우 관리자가 이를 수정하곤 했습니다. 방법을 바꿔봤자 소용없어모두하나만 수정하고 예상치 못한 부작용을 피하고 싶을 때 Apache http 서버(예제)를 시작할 수 있습니다.
일반적으로 저는 개인적으로 systemd 서비스 파일이 서비스를 제어하는 보다 깔끔한 방법이라고 생각하며, 서비스 제어를 처음 접하는 Linux 시스템 전반에 걸쳐 이를 채택할 충분한 이유가 있습니다. 작지만 목소리가 큰 사용자 커뮤니티는 systemd가 사악하다고 생각합니다. 좋아요
그러나 원하는 대로 사용자 정의할 수 있는 WSL 환경에서는 셸에 들어가기 전에 ENV 값을 미리 로드할 수 없습니다. 특히 플랫폼 간 스크립트 호환성을 테스트하기 위해 /bin/sh를 사용하려고 할 때(ZSH가 있습니다) Mac 사용자이므로 내 Bash 스크립트가 종종 충돌합니다.)
이는 모두 컴퓨터의 로컬 콘텐츠입니다. 구성을 넣어당신의개인 쉘은 개인 ~/.zshrc에 있습니다.