그래픽 로그인 시 .profile에서 기능을 내보내는 방법

그래픽 로그인 시 .profile에서 기능을 내보내는 방법

저는 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 및 kshOpenBSD)에서 위장된 것과 같은 다른 셸은 환경을 정리하고 명시적으로 허용된 문자를 제외하고 이름에 포함된 모든 환경 변수를 제거합니다. 이외의 문자.

/bin/shsystem()쉘은 애플리케이션이 다른 프로세스를 시작하기 위해 호출할 때 사용됩니다.

이 모든 것은 의미한다귀하가 (Ubuntu에) /bin/sh있고 터미널에 있는 최종 대화형 셸의 환경이 호출을 통해 또는 다른 방식으로(부모에서 자식으로 상속을 통해) 전달된 경우 함수가 사라집니다1 .dashbashsystem()/bin/sh

해결책~/.bashrc함수는 별칭이 정의된 곳에 정의됩니다. 또는 터미널에서 bash로그인 셸을 생성하도록 하세요.

1안타깝게도 저는 GDM이나 Ubuntu를 실행하지 않기 때문에 현재 strace로그인 프로세스와 관련된 프로세스를 실행하여 실제로 무슨 일이 일어나고 있는지 확인할 수 없습니다.


다른 쉘이 호출될 때 bash한 쉘과 다른 쉘 사이에서 사라지는 함수를 보여주는 예:bashdash

$ foo () { echo hello; }
$ export -f foo

$ dash -c 'bash -c foo'
bash: foo: command not found

yash기능을 제거하지 않는 대체 예를 사용하면 다음과 같습니다 .

$ yash -c 'bash -c foo'
hello

마찬가지로 kshOpenBSD에서 정리하는 동안 다음을 수행 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

관련 정보