bash에서 전역 변수를 하위 프로세스로 내보내는 방법

bash에서 전역 변수를 하위 프로세스로 내보내는 방법

저는 Openbox 창 관리자와 함께 Arch와 bash를 사용하고 있습니다.
모든 것이 최신 상태입니다.
Openbox는 다음과 같이 구성됩니다.rc.xml

내부적으로는 일반적으로 필요한 일련의 유용한 명령을 단축키에 연결하기 rc.xml위해 호출합니다 .bash -c 'command1; command2; etc'

rc.xml다음과 같이 정의된 단축키가 있습니다

<keybind key="1"><action name="Execute"><command>bash -c '
command1;
command2;
etc;
yad --timeout=1 --text="$pos_x x $pos_y";
'</command></action></keybind>

$pos_x전역적으로 정의 되어 표시되지 않는 변수를 제외하고는 모두 예상대로 작동하며 완벽하게 작동합니다 $pos_y.

이는 .bashrc다음과 같이 정의됩니다.

export pos_x=1000  
export pos_y=500  

새 bash 쉘 터미널 창을 열고 입력하면 예상되는 1000 x 500 이
echo "$pos_x x $pos_y"
표시됩니다 .

그러나 이 새 터미널 창에 입력하면 bash -c 'echo "$pos_x x $pos_y"'
자식 프로세스가 전역 변수를 상속하지 않기 때문에 아무것도 표시되지 않습니다.

입력하면 bash -c 'source ~/.bashrc; echo "$pos_x x $pos_y"'
아무것도 표시되지 않으므로 하위 프로세스에서 .bashrc를 가져오는 것은 도움이 되지 않습니다.

정의된 전역 변수를 .bashrc하위 프로세스에 전달하는 방법은 무엇입니까?

나는 주위를 둘러보았지만 어떤 답도 찾을 수 없었다.

답변1

Arch의 기본 설정에는 ~/.bashrc파일 상단에 다음 줄이 포함되어 있습니다.

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

이로 인해 비대화형 쉘이 해당 행에서 파일 읽기를 중지합니다. bash -c비대화형 셸이 시작되므로 파일 ~/.bashrc전체를 읽을 수 없으므로 변수가 정의되지 않습니다.

따라서 다음을 시도해 볼 수 있습니다.

  1. ~/.profile대신 변수를 넣으십시오 ~/.bashrc. 어쨌든 이것은 전역 변수에 대한 자연스러운 위치입니다. 로그인 관리자가 이 내용을 읽는 한 /.profile작동할 것입니다.

  2. 다른 파일을 사용하십시오. 거기에 변수 정의를 넣을 필요가 없습니다 ~/.bashrc. 변수 정의를 넣은 ~/foo다음 명령을 실행하기 만 하면 됩니다 bash -c '. ~/foo; echo "$pos_x x $pos_y".

  3. 읽기를 중지하는 처음 부분에 표시한 줄 위에 변수 정의를 배치합니다 ~/.bashrc.

답변2

~에서GNU Bash 매뉴얼, 6.2 Bash 시작 파일:

Bash가 대화형 로그인 셸로 호출되는 경우/etc/profile, 또는 파일이 존재하는 경우 먼저 파일에서 명령을 읽고 실행하는 --login 옵션이 있는 비대화형 셸로 사용됩니다 . 파일을 읽은 후 ~/.bash_profile, ~/.bash_login, 순서대로 찾아 ~/.profile명령어를 읽고 실행한다. 첫 번째존재하며 읽을 수 있습니다. ...

Bash가 비대화식으로 시작될 때예를 들어, 쉘 스크립트를 실행하려면 환경에서 BASH_ENV 변수를 찾아 그 값이 나타나면 확장하고, 확장된 값을 읽고 실행할 파일 이름으로 사용합니다.

따라서 환경을 올바르게 설정하려면 Bash가 대화식으로 시작되든 비대화식으로 시작되든 단순히 갖는 것만으로는 충분하지 않으며 ~/.bash_env변수를 설정 BASH_ENV하고 이를 가리키며 대화형 모드에서 명시적으로 가져와야 합니다.

Bash 관련 항목을 Bash 관련 파일에 넣고 ~/.profile다른 셸에서 계속 작동하는 일반 설정을 유지합니다(언젠가 로그인 셸을 변경하기로 결정한 경우).

먼저 ~/.bash_profile다음 내용으로 파일을 만듭니다.

 [ -f "$HOME/.profile" ] && source "$HOME/.profile"

 if [ -z "$POSIXLY_CORRECT" ]; then
     [ -z "$BASH_ENV" ] && export BASH_ENV="$HOME/.bash_env"
     source "$BASH_ENV"
 fi

"$HOME/.bash_env"그런 다음 모든 Bash 관련 변수와 함수를 포함하는 파일을 만듭니다.

순서가 중요합니다. 소스 줄을 ~/.profile맨 위에 놓으면 ~/.bash_profileBash를 실행할 때 거기에 정의된 변수를 재정의할 수 있습니다.

BASH_ENV변수가 참조하는 파일이 원격 쉘 데몬(보통 rshd) 또는 보안 쉘 데몬 에 의해 호출될 때 얻은 것인지 확인하지 않았습니다 sshd. Bash 매뉴얼을 다시 인용하자면,

Bash가 이러한 방식으로 비대화형으로 실행되고 있다고 판단하면 명령을 읽고 실행합니다 ~/.bashrc(파일이 존재하고 읽을 수 있는 경우).

다음을 포함하는 것을 만드는 ~/.bashrc것이 좋습니다 .

 if [ -z "$POSIXLY_CORRECT" ]; then
     [ -z "$BASH_ENV" ] && export BASH_ENV="$HOME/.bash_env"
     source "$BASH_ENV"
 fi

이 경우 다음을 단순화할 수 있습니다 ~/.bash_profile.

 [ -f "$HOME/.profile" ] && source "$HOME/.profile"
 [ -f "$HOME/.bashrc" ] && source "$HOME/.bashrc"

마지막으로 다음 항목에 여러 항목이 포함되지 않도록 보호하고 싶습니다 ~/.bash_env.

[ -n "$BASH_ENV_VERSION" ] && return 0
BASH_ENV_VERSION=.....

...

export~/.bash_env참고: 현재 셸에서 함수 정의에 액세스할 수 있도록 하려면 스크립트를 가져와야 하기 때문에 변수(또는 전체 파일의 모든 변수)를 지정하는 것은 의미가 없습니다 . 같은 이유로 우리가 만드는 파일에는 shebang 줄이 필요하지 않습니다.

우리는 대화형 로그인 쉘과 비대화형 쉘을 모두 다루었습니다. 주의 깊은 독자들은 누락된 부분이 로그인이 아닌 대화형 셸이라는 점에 반대할 수도 있습니다. 운 좋게도 위의 단계에서는 다음 단계를 수행합니다.

로그인 쉘이 아닌 대화형 쉘을 시작할 때 Bash는 파일이 존재하는 경우 ~/.bashrc에서 명령을 읽고 실행합니다.

관련 정보