bash가 환경 변수에 파싱 / 실행 항목을 넣는 이유는 무엇입니까?


9

bash 의 shellshock 버그는 환경 변수를 통해 작동합니다. 솔직히 나는 다음과 같은 기능이 있다는 사실에 놀랐습니다.

"env vars를 통한 함수 정의 전달"

따라서이 질문은 완벽하게 공식화되지는 않았지만이 기능을 사용해야하는 예 또는 사례를 묻는 것입니까?

보너스. 다른 쉘 zsh, dash 등에 도이 기능이 있습니까?


env vars를 사용하여 함수 정의를 전달합니다. "환경 변수를 단순히 사용 가능 / 접근 가능하게 유지하지 않는 이유는 무엇입니까?" ?
Anthon

@Anthon 의견에 감사드립니다. 어쩌면 나는 더 명확하고 바꿔야 할 것입니다. env vars를 통해 함수 정의를 전달할 수 있어야하는 이유는 무엇입니까?
humanandANDpeace

1
100 % 확신 할 수는 없지만 GNU parallel가 여러 bash 인스턴스를 호출하는 경우 GNU 가 함수 정의를 배포 하는 방식이라고 생각 합니다. 그렇게하지 않으면 파일에 인스턴스를 작성해야하며, 호출 된 각 인스턴스가 읽은 다음 해당 파일을 제거 할 수있는시기와 같은 문제를 처리해야합니다.
Anthon

2
스레드 에는 역사가 있습니다. 그러나 내 보낸 함수는 미쳤다 . 새 쉘이 이전 쉘 실행 가능 명령을 상속 .dot하도록하려면 이전 쉘과 동일한 파일 을 소스로 사용하십시오. 그것이 어떻게 이루어 졌는지 그리고 그것이 의미가 있습니다. 또는 execing 할 때 새로운 쉘에 파일을 입력으로 공급 합니다. 일단 읽은 후에는 파일이 커널에 의해 캐시됩니다.
mikeserv

@mikeserv 쉘 쇼크의 많은 부분이이 기능과 관련이 있다는 것을 이해하고 있습니까?
humanandANDpeace

답변:


4

스크립트가 다른 스크립트를 호출하면 부모 스크립트의 변수를 내보내고 자식 스크립트에서 볼 수 있습니다. 함수 내보내기는 명백한 일반화입니다. 부모에서 함수를 내보내고 자식에서 볼 수있게하십시오.

환경은 프로세스가 임의의 데이터를 자식에게 전달할 수있는 유일한 편리한 방법입니다. 널 바이트를 포함하지 않는 문자열로 데이터를 마샬링해야하므로 쉘 기능에는 어려움이 없습니다. 공유 메모리 블록 또는 파일 디스크립터를 통해 전달 된 임시 파일과 같은 다른 잠재적 인 방법이 있지만, 이로 인해 수행 할 작업을 모르거나 닫는 중간 프로그램에 문제가 발생할 수 있습니다. 프로그램은 알지 못하거나 신경 쓰지 않는 변수가 포함 된 환경에서 실행되므로 덮어 쓰거나 지우지 않습니다.

함수 이름을 환경 변수의 이름으로 사용하는 것은 이상한 일입니다. 우선, 내 보낸 변수가 같은 이름의 내 보낸 함수와 충돌한다는 것을 의미합니다.

내 보낸 기능은 이전 기능입니다. SVR2 의 Bourne 쉘 함수가 추가되었고 같은 해에 릴리스 된 버전 8 쉘 (1984) 에서 함수를 내보냈습니다 . 이 셸에서 변수와 함수는 동일한 네임 스페이스를 사용했습니다. 함수 내보내기가 어떻게 작동했는지 모르겠습니다. 가보 쉘 기능을 가지고 있지만를 내 보내지 않는 Bourne의 변형을 기반으로한다.

ATT ksh는 아마도 함수 내보내기를 지원하지만 소스를 보거나 재생하는 것은 ksh93u에서 볼 수 없습니다.

env -i /usr/bin/ksh -c 'f=variable; f () { echo function; }; typeset -fx f; /usr/bin/env; ksh -c f'
_=*25182*/usr/bin/env
PWD=/home/gilles
SHLVL=1
A__z="*SHLVL
ksh: f: not found

Ksh의 퍼블릭 도메인 클론 (pdksh, mksh), dash 및 zsh는 내보내기 기능을 지원하지 않습니다.


1
감사합니다! 따라서 기능을 내 보내지 않으면 기능이 손실되지만 대시, zsh 및 pdksh 등과 같은 기능이 부족한 쉘이 있습니다.
humanityANDpeace

그러나 bash에서 함수를 내보낼 때와 같은 변수로 들어갑니다 BASH_FUNC_f%%=() { echo hi }. bash가 다른 환경 변수를 구문 분석하는 이유는 무엇입니까? BASH_FUNC_g%%내가 전화 할 때 왜 왜 파싱 f하겠습니까? (분명히, 사전 셸 쇼크는 환경 변수가 방금 전화했다 fg-하지만 난 아직도 왜 궁금하네요 g내가 전화하지 않는 경우 구문 분석 한 것입니다 g내 스크립트)
변성

@Met 어떤 환경 변수가 함수 정의인지 알아 내려면 모든 환경 변수를 조사해야합니다. 그것은 사실을 암기하고 필요할 때까지 함수 코드를 파싱하는 것을 피할 수 있지만, 약간의 이득을 얻기 위해서는 추가적인 복잡성이 있습니다. 두 가지가 아닌 한 가지 유형의 함수를 사용하는 것이 더 쉽습니다 ( "정상 함수"및 "조금 파싱이 필요한 환경 변수의 함수").
Gilles 'SO- 악마 그만해'

명확하지 않습니다. 분명히해야 할 것은``라고 불리는 것을 실행할 때 f(1) ``이라는 셸 함수를 f확인하고 (2)라는 환경 변수를 확인 f하고 구문 분석하려고 시도했을 것입니다. (3) 확인 각각 PATH라는 실행을위한 구성 요소 f. 쉘 시작시 모든 환경 변수를 쉘 코드로 구문 분석하는 방법이 덜 복잡한 것처럼 보일 수 있습니까?
변성

@Metamorphic 모든 명령에서 수행해야하는 다른 단계를 추가 할 것을 제안합니다. 또한 함수를 정의하거나 정의 unset -f foo하지 않을 때 (이후 bash는 foo더 이상 환경에서 함수 정의를 찾지 않아야 함 ) 함수를 나열 할 때 ( declare -f모든 환경 변수를 읽는 것 이외의 처리 방법은 무엇입니까?) 다른 단계를 추가 해야합니다. 그리고 내가 생각하지 않는 다른 것. 대부분의 디자인을 생략했기 때문에 디자인이 더 쉬워 보입니다. 반대로 시작시 모든 작업을 수행하는 것은 단일 코드이며 모든 작업이 완료됩니다.
Gilles 'SO- 악마 그만해'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.