저는 GDM과 함께 Ubuntu 18.04를 사용하고 있습니다. 내 .bashrc 파일에서 일부 bash 기능을 내보내려고 합니다 .profile
.
설명된 대로이것은 매우 좋은 자료입니다.bashrc
, 의 주요 차이점은 .profile
후자가 로그인 쉘에서만 실행된다는 것입니다.
.profile
나는 내보내기를 사용하여 에 맞지 않는 것을 얻는 데 성공했습니다 . 따라서 그래픽 로그인 셸에서도 해당 정보를 성공적으로 얻을 수 있다는 것을 .bashrc
알고 있습니다 . .profile
예를 들어 내 $PATH
정의는 다음과 같습니다.
export PATH="something/bin:$PATH"
.bashrc
이것을 에 넣으면 "something/bin"
서브쉘을 실행할 때마다 다시 삽입됩니다.
$ echo $PATH
something/bin:/usr/local/bin:/usr/bin:/bin
$ bash
$ echo $PATH
something/bin:something/bin:/usr/local/bin:/usr/bin:/bin
그러나 이와 같은 함수를 내보내는 것은 그래픽 로그인에서는 작동하지 않는 것 같습니다.
hello () { echo "hello"; }
export -f hello
bash -l
로그인했든 콘솔에서 로그인했든 상관없이 잘 작동합니다.
따라서 질문은 다음과 같습니다. .profile
소스를 분명히 얻은 경우(환경 변수가 성공적으로 내보내지고 명시적으로 소스가 있는 것으로 표시되는 경우 /etc/gdm3/Xsession
) 내보낸 함수가 작동하지 않는 이유는 무엇입니까?
답변1
이는 "에 설명된 문제의 특정 사례일 가능성이 높습니다.내 BASH_FUNC_foobar%% 환경 변수가 쉘 하위 프로세스에 설정되지 않은 이유는 무엇입니까?".
에서 함수를 내보내면 bash
특별한 이름을 가진 환경 변수가 생성됩니다.
$ foo () { echo hello; }
$ export -f foo
$ env
...
BASH_FUNC_foo%%=() { echo hello
}
...
쉘은 쉘 함수가 이를 수행할 수 없기 때문에 이를 수행합니다.진짜다음으로 내보내기기능이므로 "특수 환경 변수"로 변환됩니다. 환경 변수는 단순한 키-값 문자열 쌍만 될 수 있습니다.
bash
쉘이 이러한 유형의 환경 변수를 사용하여 환경을 상속 하면 해당 변수가 bash
함수임을 알고 적절한 이름으로 해당 함수를 인스턴스화합니다.
~에 따르면POSIX 표준:
POSIX.1-2017 셸의 유틸리티 및 유틸리티 볼륨은 다음을 포함하는 환경 변수 이름을 사용합니다.대문자, 숫자 및
<underscore>
(_
)이식 가능한 문자 세트의 문자이며 숫자로 시작하지 않습니다.구현에서는 다른 문자를 허용할 수 있습니다(MAY). 애플리케이션은 그러한 이름의 존재를 허용해야 합니다.대문자와 소문자는 고유한 정체성을 유지해야 하며 함께 접혀서는 안 됩니다. 소문자로 된 환경 변수 이름을 포함하는 네임스페이스는 애플리케이션용으로 예약되어 있습니다. 애플리케이션은 표준 유틸리티의 동작을 수정하지 않고도 이 네임스페이스의 이름을 사용하여 환경 변수를 정의할 수 있습니다.
이 기사에 따르면 %
환경 변수를 포함하는 이름은 허용되지만 /bin/sh
일부 시스템( dash
예: Ubuntu 및 ksh
OpenBSD)에서 위장된 것과 같은 다른 셸은 환경을 정리하고 명시적으로 허용된 문자를 제외하고 이름에 포함된 모든 환경 변수를 제거합니다. 이외의 문자.
/bin/sh
system()
쉘은 애플리케이션이 다른 프로세스를 시작하기 위해 호출할 때 사용됩니다.
이 모든 것은 의미한다귀하가 (Ubuntu에) /bin/sh
있고 터미널에 있는 최종 대화형 셸의 환경이 호출을 통해 또는 다른 방식으로(부모에서 자식으로 상속을 통해) 전달된 경우 함수가 사라집니다1 .dash
bash
system()
/bin/sh
해결책~/.bashrc
함수는 별칭이 정의된 곳에 정의됩니다. 또는 터미널에서 bash
로그인 셸을 생성하도록 하세요.
1안타깝게도 저는 GDM이나 Ubuntu를 실행하지 않기 때문에 현재 strace
로그인 프로세스와 관련된 프로세스를 실행하여 실제로 무슨 일이 일어나고 있는지 확인할 수 없습니다.
다른 쉘이 호출될 때 bash
한 쉘과 다른 쉘 사이에서 사라지는 함수를 보여주는 예:bash
dash
$ foo () { echo hello; }
$ export -f foo
$ dash -c 'bash -c foo'
bash: foo: command not found
yash
기능을 제거하지 않는 대체 예를 사용하면 다음과 같습니다 .
$ yash -c 'bash -c foo'
hello
마찬가지로 ksh
OpenBSD에서 정리하는 동안 다음을 수행 ksh93
하지 zsh
마십시오.
$ ksh -c 'bash -c foo'
bash: foo: command not found
$ ksh93 -c 'bash -c foo'
hello
$ zsh -c 'bash -c foo'
hello
위 출력의 모든 경우에 hello
개입 쉘은 특별히 명명된 환경 변수가 함수를 형성한다는 사실을 알지 못합니다.
$ yash -c 'foo'
yash: no such command `foo'
$ ksh93 -c 'foo'
ksh93: foo: not found
$ zsh -c 'foo'
zsh:1: command not found: foo