인라인으로 선언된 환경 변수를 구별하는 영리한 방법이 있습니까?

인라인으로 선언된 환경 변수를 구별하는 영리한 방법이 있습니까?

자식 프로세스로 내보낸 인라인 선언/정의 환경 변수와 이미 존재하거나 상속된 환경 변수를 구별하고 싶습니다.

$ export NODEJS=8
$ FU=BAR sh -c 'echo $FU $NODEJS'

구체적인 사용 사례는 cmd 래퍼/데코레이터입니다.캡슐화컨테이너 사용량(이것은 단지 예일 뿐입니다).

/tmp $ cat ./go.sh 
#!/bin/sh
set -eu

docker run \
    --rm \
    --volume $PWD:/opt/main \
    --workdir /opt/main \
golang:1.15 go "${@--h}"
/tmp $ go version
go version go1.15.5 darwin/amd64
/tmp $ mkdir -p /tmp/bin
/tmp $ ln -sf /tmp/go.sh /tmp/bin/go
/tmp $ chmod +x /tmp/go.sh 
/tmp $ PATH=/tmp/bin:$PATH
/tmp $ go version
Unable to find image 'golang:1.15' locally
1.15: Pulling from library/golang
756975cb9c7e: Pull complete 
d77915b4e630: Pull complete 
5f37a0a41b6b: Pull complete 
96b2c1e36db5: Pull complete 
145393847161: Pull complete 
3f8843661db9: Pull complete 
218d240e42d4: Pull complete 
Digest: sha256:0edb8df3d92a2ccf84d3245c8b0cc31edd6d23f9c3da3e07c8e2bd96eea34547
Status: Downloaded newer image for golang:1.15
go version go1.15.6 linux/amd64

위 래퍼 스크립트의 최종 사용자가 Darwin 호스트에서 호출하든 컨테이너에서 호출하든 인터페이스 및/또는 기대치에 차이가 있어서는 안 되기 때문에 캡슐화를 강조합니다. 이는 다음과 같은 빈 환경이 없음을 의미합니다.

/tmp $ env -i FU=BAR sh -c 'echo $FU $NODEJS'
BAR

환경 변수를 Docker 런타임에 전달하려면 다음을 수행할 수 있습니다.

$ cat <<eof | head -n3
> docker run \
> --rm \
> --volume $PWD:/opt/main \
> --workdir /opt/main \
> $( env -0 | xargs -0 -L1 printf '--env "%s"\n' ) \
> golang:1.15 go "${@--h}"
> eof
docker run --rm --volume /tmp:/opt/main --workdir /opt/main --env "TERM_PROGRAM=Apple_Terminal"
--env "SHELL=/bin/bash"
--env "TERM=xterm-256color"
...

이는 쉘 운영 환경(예: um, 등)을 무시할 때 큰 혼란을 초래할 수 있습니다. ENVS와 같은 추가 매니페스트를 사용하여 사용하려는 환경을 화이트리스트에 추가할 수 있지만 이는 여러 가지 이유로 문제가 됩니다 SHELL.PATH

 $ cat /tmp/go.sh 
#!/bin/sh
set -eu

cat <<eof
docker run \
    --rm \
    --volume $PWD:/opt/main \
    --workdir /opt/main \
    $( echo $ENVS | xargs -n1 -- sh -c 'printf -- "--env %s=%s\n" $1 ${!1}' _) \
golang:1.15 go "${@--h}"
eof
$ ENVS="FU NODEJS" FU=BAR /tmp/go.sh 
docker run  --rm    --volume /tmp:/opt/main     --workdir /opt/main     --env FU=BAR
--env NODEJS=8 golang:1.15 go "-h"

첫째, 정말 혼란스럽고 둘째, 래퍼의 예상 동작이 기본 대상의 예상 동작과 일치해야 한다는 원칙을 위반합니다. 아래와 같이 go 명령에 env를 전달했는데 작동하지 않고 ENVS.

# fails to build appropriately targeted binary, but doesn't fail to build
$ GOOS=linux GOARCH=ppc64 go build
# this makes me mad
$ ENVS="GOOS GOARCH" GOOS=linux GOARCH=ppc64 go build

뻔한 하드 코딩 외에 이 문제를 해결할 수 있는 다른 방법이 있는지는 모르겠지만, 지나치게 영리하고 간결한 것이 있다면 보고 싶습니다.

관련 정보