하위 쉘에서 상위 쉘로 VAR을 내보내는 방법은 무엇입니까?

하위 쉘에서 상위 쉘로 VAR을 내보내는 방법은 무엇입니까?

Korn 쉘 스크립트가 있습니다

#!/bin/ksh
# set the right ENV
case $INPUT in
abc)
  export BIN=${ABC_BIN}
  ;;
  def)
  export BIN=${DEF_BIN}
  ;;
  *)
  export BIN=${BASE_BIN}
  ;;
esac
# exit 0 <- bad idea for sourcing the file

이제 이러한 VAR은 하위 쉘에서만 내보내지지만 상위 쉘에서도 설정되기를 원하므로 프롬프트가 표시될 때 해당 VAR은 여전히 ​​올바르게 설정됩니다.

나는 대해 알고있다

. .myscript.sh

하지만 '소싱' 없이 이를 수행할 수 있는 방법이 있습니까? 내 사용자는 종종 '소스'를 잊어버립니다.


EDIT1: "exit 0" 부분 제거 - 이것은 내가 먼저 생각하지 않고 입력한 것입니다.

EDIT2: 왜 이것이 필요한지에 대한 자세한 내용을 추가하려면: 내 개발자는 (단순화를 위해) 2개의 앱인 ABC & DEF에 대한 코드를 작성합니다. 모든 앱은 별도의 사용자 usrabc 및 usrdef에 의해 프로덕션에서 실행되므로 $BIN, $CFG, $ORA_HOME 등을 해당 앱에 맞게 설정했습니다.

그래서

  • ABC의 $BIN = /opt/abc/bin # 위 스크립트의 $ABC_BIN
  • DEF의 $BIN = /opt/def/bin # $DEF_BIN

등.

이제 개발자 상자에서 개발자는 자신의 사용자 계정 'justin_case'로 ABC와 DEF를 동시에 개발할 수 있으며, ENV var 설정을 앞뒤로 전환할 수 있도록 파일 소스를 제공합니다(위). ($BIN은 한 번에 $ABC_BIN을 가리켜야 하며 그 다음에는 $BIN=$DEF_BIN으로 전환해야 합니다)

이제 스크립트는 동일한 앱 등의 병렬 개발을 위해 새 샌드박스도 생성해야 합니다. 이로 인해 샌드박스 이름 등을 묻는 대화식으로 작업을 수행하게 됩니다.

  • /홈/justin_case/sandbox_abc_beta2
  • /홈/justin_case/sandbox_abc_r1
  • /홈/justin_case/sandbox_def_r1

내가 고려한 다른 옵션은 별칭을 작성하여 모든 사용자 프로필에 추가하는 것입니다.

  • 별칭 'setup_env=. .myscript.sh'

그리고 그것을 실행

  • setup_env 매개변수1 ... 매개변수X

지금은 이게 더 이해가 되네요

답변1

제 생각엔 '할 수 없는' 문제인 것 같아요...

첫째, 끝에 0이 있기 때문에 해당 스크립트를 소싱하고 싶지 않을 것입니다.

둘째, Unix 하위 프로세스는 상위 환경을 직접 변경할 수 없습니다. 그렇지 않으면 모든 종류의 미친 일이 가능할 것입니다.

기본 프로필이나 bashrc 파일을 사용하여 환경에 무언가를 추가할 수 있습니까? 아니면 실행하려는 프로그램에 대한 래퍼를 작성할 수 있습니까?

"래퍼" 개념에 대해 자세히 설명하겠습니다.

프로덕션 또는 개발을 원하는지에 따라 환경 변수 "OPTIONS"에서 PROD 또는 DEV를 사용하여 snoopy 프로그램을 실행한다고 가정해 보겠습니다. 설정되지 않은 경우 snoopy가 생산 및 개발을 위해 데이터베이스를 지우는 등 이상한 작업을 수행한다고 가정해 보겠습니다.

"snoopy" 이름을 snoopy.bin(또는 .snoopy.bin)으로 바꿉니다.

그런 다음 다음 내용을 포함하는 "snoopy"라는 이름의 동일한 위치에 스크립트를 넣습니다.

#!/bin/sh

export OPTIONS

case "$OPTIONS" 
in
  PROD) ;;
  DEV) ;;
  *) OPTIONS=DEV ;;
esac

#the binary is actually named snoopy.bin 

exec "$0.bin" "$@"

실제 파일에 문제를 일으키고 싶지 않다면 사용자의 PATH에서 실제 스누피 프로그램보다 앞에 있는 파일 시스템 어딘가에 이 스크립트를 배치하고 스크립트의 exec 문에 바이너리에 대한 전체 경로를 지정하세요.

답변2

답은 소싱이다. 소싱을 사용하면 스크립트에 변수를 포함할 수 있습니다.현재의쉘이지만 결코 그 부모가 아닙니다. 사실입니다. 현재 쉘이 닫힐 수 있으므로 종료 명령이나 이와 유사한 명령을 사용하지 않도록 주의해야 합니다.

"."를 사용하여 스크립트를 소스로 지정할 수 있습니다. 즉,

. ./myscript.ksh

답변3

아마도 노력한다면...

#!/bin/bash

mknod fifo p

(
       echo 'value' > fifo &
)

VARIABLE=`cat fifo`
rm fifo

정확히 말하면 변수 내보내기는 아니지만 상위 프로세스와의 기본적인 통신을 제공할 수 있습니다.

답변4

알았어, 이제 웃지 마. 매우 빠르고 더러운 해결책은 다음을 추가하는 것입니다.

echo "Please copy and paste this command:"
echo ""
echo "export BIN=\"$BIN\""

당신의 스크립트에.

또 다른 접근법. exec스크립트의 하위 $SHELL일 수도 있고 다른 프롬프트가 있을 수도 있습니다(혼란을 줄이기 위해 작업 중인 환경을 사용자에게 알리려면 $PS1을 변경하세요) .

또 다른 접근법(내가 좋아하는 것). 사용자가 스크립트 소스를 잊어버린 경우, 그 이유는 무엇입니까? 소싱은 정확히 표준적인 방법입니다. 아마도 그들에게 상기시키는 좋은 방법은 첫 번째 줄( #!/bin/sh)을 제거한 다음 chmod a-x그 줄을 제거하는 것입니다. 그 후에도 계속 소스를 얻을 수 있지만 실수로 실행될 수는 없습니다.

호언장담: 전체적으로, 당신은 처음부터 이상한 생각을 갖고 있었던 것 같습니다. 어쩌면 이상하지 않을 수도 있습니다. 저는 유닉스 스타일이 아닌 스타일이라고 말하고 싶습니다. 나는 내 인생에서 부모에게 환경을 내보낼 필요가 없었습니다. 나는 비슷한 상황을 본 적이 있습니다. 단일 Oracle 계정에 대해 세 가지 다른 환경 중 어느 것을 설정할지 묻는 login .profile입니다. 나쁜 생각이지만 결국 사용자는 sudo로 마이그레이션하는 것을 선호하는 것으로 나타났습니다(그들은 3개의 다른 oraxxx 계정으로 sudo를 했습니다). 내가 물어봐도 된다면 당신은 무엇을 성취하려고 하는가?

관련 정보