쉘 스크립트가 호출되었던 원래 환경으로 복원이 가능한가요? 나는 원래 환경에 접근하는 능력에 의존하는 프로그램을 작성하려는 것이 아니다. 그것이 맞는지 알고 싶다.접근성 보장.
새 환경 변수를 생성하고 PATH 값을 변경하는 간단한 쉘 스크립트가 있습니다.
#!/bin/sh
PATH=/usr/bin
NEW_VAR=new_var_value; export NEW_VAR
env
원래 값을 복원하는 방법이 있습니까, 아니면 쉘 스크립트를 실행할 때 처음에 존재하지 않도록 PATH
지시하는 방법이 있습니까 ?NEW_VAR
실행 파일의 경로가 모두 시스템 호출 초기에 설정된다는 argv
것을 알고 있지만 실행 파일이 "어디" 또는 "어떻게" 저장되어 있는지는 잘 모르겠습니다. 내 생각에는 , 를 사용하여 매개변수 벡터와 환경을 조작하는 기능이 실제로 및 의 기본 설정을 변경하지 않는 것 같습니다. 셸 내부에는 다른 명령(예:)을 호출할 때 새 호출이 올바른 명령을 사용하는지 확인하는 논리만 있습니다.envp
execv*(2)
shift
export
unexport
argv
envp
execv*(2)
envp
some-command | LC_ALL=C sort
답변1
대부분의 시스템에서는 이 명령을 사용하여 명령이 실행되는 동안 ps
환경을 표시할 수 있습니다. 이식성이 없으며 모든 시스템이 안정적인 구문 분석을 허용하는 것은 아니지만 원하는 것이 특정 Unix 변형에 작동하는 방식으로 초기 환경의 "흥미로운" 부분을 추출하는 것이라면 쉽습니다. 예를 들어 Linux 및 *BSD에서는 다음과 같습니다.
ps eww $$
또는 Solaris 및 Linux의 경우:
cat /proc/$$/environ
또는 Solaris 및 AIX의 경우:
pargs -e $$
환경의 이전 콘텐츠를 숨겨야 하는 경우 모든 셸 프로세스(백그라운드 하위 셸 포함)가 종료되었는지 확인하세요. 누출되지 않는 방식으로 데이터를 전달하려면 환경 변수 대신 파이프를 사용하십시오.
exec sh -c 'unset pw; pw=$PASSWORD; unset PASSWORD; printf %s "$pw" | exec theprogram'
대부분의 (모두 최신?) Unix 변형에서 프로세스 환경은 동일한 사용자에게만 표시됩니다. 일반적으로 실행 중인 사용자는 매개변수만 볼 수 있습니다 ps
. 따라서 환경 전체에 기밀 데이터를 전달하는 것은 괜찮습니다. 이를 제거하는 것은 기본 보안이 아니라 강화의 문제일 뿐입니다.
답변2
POSIX 자체는 이를 수행하는 기본 방법을 제공하지 않습니다. 이 목표에 접근하는 여러 가지 방법을 생각해 볼 수 있습니다.
- 상위 환경(예:
/proc/pid/environ
Linux의 환경)에 존재하는 환경을 보고 해당 환경을 기반으로 처음부터 환경을 다시 채웁니다. 이것은 작동할 수도 있고 작동하지 않을 수도 있습니다.- 부모는 반드시 자녀가 시작했던 환경과 동일할 필요는 없습니다.
- 상위 항목이 더 이상 존재하지 않을 수 있습니다.
- 자녀가 부모의 환경에 접근할 수 없을 수도 있습니다(예: 권한 포기의 맥락에서).
- 스크립트 시작 부분(예:
export -p
또는 시작 부분 사용)에 환경을 저장하고 나중에 복원합니다./proc/self/environ
이것은 잘 작동하지만 이를 복원하려면 논리를 직접 작성해야 합니다. - 새 환경 변수를 설정할 때는 이전 변수 값을 먼저 저장하는 함수를 통해 수행한 다음 동일한 함수를 통해 이를 복원할 수 있습니다(또는 예를 들어 에 저장하여 수동으로 수행
$OLD_PATH
). 이것은 효과가 있지만 번거롭고 잊어버리기 쉽습니다. 예를 들어:
$OLD_PATH=$PATH
# do something
$PATH=$OLD_PATH
답변3
수정하기 전에 환경 상태를 알고 싶다면 작업을 수행하기 전에 환경을 저장해 보는 것은 어떨까요? 예를 들어,
#!/bin/sh
PATH_orig=$PATH; # save the original PATH
case ${NEW_VAR++} in
? ) echo 'Achtung: NEW_VAR is already in the original environment' ;;
* ) echo 'NEW_VAR not found in the original environment' ;;
esac
OLD_ENV=$(export -p) # will save your original env in a source-able manner
### And now make your changes...
PATH=/usr/bin
NEW_VAR="foo"; export NEW_VAR