bash / dash, 대화식 / 비 대화식, 로그인 / 비 로그인의 모든 조합이 환경 변수를 가져 오도록 환경 변수를 어디로 내 보내야합니까?


11

질문에 대한 동기는 다음과 같습니다.

Unity 데스크톱과 함께 Ubuntu 12.04 LTS 2를 사용하고 있습니다. .bashrc 파일에서 PATH 변수에 여러 디렉토리를 추가하고 JAVA_HOME과 같은 몇 가지 환경 변수를 정의합니다. 터미널에서 응용 프로그램을 시작하면 (내 기본 셸 실행) 훌륭하게 작동하지만 Unity 런처를 사용하는 여러 바로 가기의 경우 #! / bin / sh를 사용하도록 정의 된 것으로 보이는 앱을 실행합니다. / bin / dash의 별칭이며 ~ / .bashrc 또는 ~ / .profile의 내용을 선택하지 않습니다.

.bashrc 변경 사항을 강제로 적용하기 위해 / bin / sh 대신 / bin / bash를 사용하도록 이러한 모든 단축키를 변경할 수 있다고 가정하지만 실제로는 해키처럼 보입니다.

Ubuntu 12.04 (기본적으로) 별명 / bin / sh가 / bin / dash이고 기본 쉘이 / bin / bash 인 경우 PATH를 수정하고 원하는 경우 환경 변수를 정의 할 수있는 단일 위치가 있습니까? 이러한 모든 상황 에서 존재해야합니다 .

  1. 비 로그인 bash 쉘을 만들 때마다 (단일 터미널을 사용하여)
  2. 로그인 bash 쉘을 작성할 때마다 (예 : ssh를 통해 원격으로 로그인)
  3. Unity 응용 프로그램 실행기를 사용할 때마다 (실행기가 / bin / sh를 사용하는 경우)
  4. cron 작업이 실행될 때마다 (/ etc / crontab에서 SHELL = / bin / sh가 제공됨).

올바르게 이해하면 다음과 같이 추측됩니다.

  • (1) / (2)는 배쉬이고 (3) / (4)는 대시이므로 (1) / (2) 및 (3) / (4)는 다릅니다.
  • (1)과 (2)는 bash가로드하기로 선택한 파일이 로그인 쉘인지 여부에 따라 달라지기 때문에 다릅니다.
  • (3) 은 로그인 한 후 어느 시점에 오기 때문에 (3)과 (4)는 다릅니다. 따라서 ~ / .profile은 부모 프로세스 중 하나에 의해 제공되고 (4)는 내가 로그인 하지 않았을 때 ~ / .profile을 읽지 못했을 때.

(쉘이 대화 형인지 여부와 같은 다른 요소가 중요하더라도 놀라지 않을 것입니다. 따라서 예상치 못한 조합이 더 많을 것입니다 ... 내 질문이 "개선되어 기쁘다" "의 경우에.)

어느 시점에서 누군가가 쉘과 독립적 인 방식으로 (또는 적어도 대시 / bash 호환 방식으로) 환경 변수를 수정하는 방법 / 위치를 알려주는 일종의 가이드를 만들어야했을 것입니다 ... 그런 가이드를 찾을 수있는 올바른 검색어를 찾지 못하는 것 같습니다.

솔루션 또는 솔루션에 대한 포인터는 대단히 감사합니다!

업데이트 :

  • 설명 : 12.04 설치 과정에서 생성 된 기본 Ubuntu 사용자이므로 별다른 문제가 없습니다. 그것은 않습니다 가지고 ~ / .profile에 (즉 명시 적으로 원 ~ / .bashrc에), 유일한 ~ / .bash * 파일의 .bashrc가, .bash_history 파일 및 .bash_logout ... 그래서 더 .bash_profile에 없다 없습니다 제시한다.
  • 범위에 대한 강조 : 정말 기본 대화 형 쉘 (bash는)와 (대시 별칭) / bin / sh을 사용한다 일어나는 모든 스크립트 이외의 쉘에 대해 걱정하지 않는다, 그래서 아무것도 가진이 복잡 할 필요가 없습니다 추가 에 대한이 tcsh / ksh / zsh / etc. 지원하다.

2
하나의 파일에 넣고 다른 rc 파일이 소스를 갖도록하십시오.
konsolebox

내가 가지고있는 대시 매뉴얼 페이지에 따르면 로그인 쉘에 대해 $ HOME / .profile을 읽어야합니다.
Etan Reisner

@konsolebox 어떤 rc 파일입니까? AFAICT, dash에는 rc 파일이 없습니다. 그리고 내가 언급했듯이 대시는 ~ / .profile의 내용을 선택하지 않는 것 같습니다.

@EtanReisner 예, 이것이 문제의 핵심입니다. 대시가 로그인 쉘로 실행되지 않고 (따라서 ~ / .profile이 소스가 아닌 경우) 어떻게해야합니까?

@Mickalot 대화식으로 대시를 실행하고 있습니까? -l 옵션을 추가하지 않으면
konsolebox

답변:


9

쉘 호출은 약간 복잡한 것입니다. bash 및 dash 매뉴얼 페이지에는 INVOCATION이것에 대한 섹션이 있습니다.

요약하면 그들은 말합니다 (man 페이지에 자세한 내용이 있습니다. 읽어보십시오).

When bash is                   | it reads
-------------------------------|----------
login shell                    | /etc/profile and then the first of ~/.bash_profile, ~/.bash_login or ~/.profile that exists.
                               |
interactive non-login shell    | /etc/bash.bashrc then ~/.bashrc
                               |
non-interactive shell          | The contents of $BASH_ENV (if it exists)
                               |
interactive (as "sh")          | The contents of $ENV (if it exists)

-

When dash is                   | it reads
-------------------------------|---------
login shell                    | /etc/profile then .profile
                               |
interactive shell              | The contents of ENV (it it exists, can be set in .profile as well as in initial environment)

나는 다른 쉘을 사용하지 않기 때문에 다른 쉘에 대해 알지 못한다. 가장 좋은 방법은 공통 환경 스크립트를 가리 키도록 두 개의 환경 변수를 설정하고 적절하지 않은 경우에 수동으로 소스를 제공하는 것입니다.


슬프게도이 문제의 핵심은 대시 테이블에서 누락 된 것입니다. Unity 데스크탑이 #! / bin / sh로 시작하는 스크립트를 호출하면 로그인하지 않은 비 대화식 대시 셸이 시작됩니다. 그래서 질문은 : 매트릭스의 다른 곳에 존재 하는 동일한 환경 변수를 어떻게 사용할 수 있습니까?

권리. 이것이 bash가 해당 슬롯에 BASH_ENV를 추가 한 이유입니다. 대시에 해당 슬롯에서 작동하는 것으로 보이지 않는 경우 대시를 시작하는 응용 프로그램 환경의 변경에 영향을 미치지 않고 해당 문제를 해결할 수 있는지 확실하지 않습니다 (대시가이를 상속 함). 이것은 @Mickalot의 .xsession (rc) 주석이 작동하는 X 환경에서 설정되는 환경 변수가 필요합니다. 이것은 지적한 바와 같이 여전히 항목 4를 남겼습니다 (그러나 실제로는 의도적이라고 생각합니다).
Etan Reisner

Ubuntu 12.04 LTS를 사용하고 있기 때문에 cron은 실제로 pixie-cron이므로 crontab 파일에서 env 변수를 정의 할 수 있습니다 ... SHELL = / bin / bash 및 BASH_ENV = ~ / .bashrc 가해 야합니까?

3

따라서 여기에는 몇 가지 방법이 있습니다. 많은 사람들이 :

ㅏ. 당신의 SH-스타일의 쉘의 모든 것들의 공통을 가지고 하나 개의 파일을 가지고 말 .shcommon과 각 .profile .bashrc .kshrc등 CETRA 단지로이 소스. .shcommon

비. 모든 것을 .profile넣고 다른 파일에서 가져옵니다.

특정 쉘 또는 대화식 대 비 대화식 쉘에 필요한 사항은 소싱하기 전에 적절한 파일로 이동할 수 있습니다. .shcommon

개인적으로 여러 파일 관리를 싫어합니다. 따라서 다음과 같은 접근 방식을 사용합니다.

먼저 필요한 모든 .profile 것들 bash와 ksh에 특정한 것들이 있기 때문에 다음을 사용하여 현재 쉘 이름을 결정합니다.

# get name of current shell
# strip leading - from login shell
export SHELLNAME="${0#-}"

그런 다음 다음과 같은 특정 쉘에 대한 명령이 있습니다 (일부는 case 문을 선호합니다).

if [ "$SHELLNAME" = 'bash' ]
then
    shopt -s checkwinsize

elif [ "$SHELLNAME" = 'ksh' ]
then
    stty erase ^?
fi

대화식 쉘에서만 실행되어야하는 명령이있는 경우 다음을 사용합니다.

# check for interactive flag i in shell options $-
# in bash and ksh you could use the following, but breaks in dash
# if [[ $- == *i* ]]
if [ "$(echo $- | grep i)" != "" ]
then
  fortune
fi

예를 들어, 모든 sh 스타일 쉘에서 공통적 인 사항 PATH은 맨 위에 갈 수 있습니다.

그런 다음 심볼릭 링크를 사용하여 모든 sh 스타일 쉘에 동일한 파일을로드합니다.

ln -s .profile .bashrc
ln -s .profile .kshrc

사이드 노트 두 개가있는 경우 .bash_profilebash는 이것을 대신로드 .profile하지만 대시와 ksh는 여전히로드됩니다. .profile 이것은 문제의 일부 일 수 있습니다.

또한 실제로 POSIX 호환 스크립트를 원하지 않는 한 #!/bin/bash스크립트에서 사용하는 #!/bin/dash것이 좋습니다. bash에는 sh가 많은 기능을 비활성화하므로 매우 훌륭하고 대시 또는 bash가 호출되는 추가 기능이 많이 있습니다.

또한 bash 매뉴얼 페이지는 .profilevs .bashrc가로 드 될 때를 잘 설명 합니다. ksh에도 비슷한 규칙이 적용됩니다. .profile로그인시 대시가로드 되고 ENV환경 변수를 사용하여 지정된 대화식 쉘을 시작할 때 파일을로드 할 수 있습니다 .profile(대시 맨 페이지도 확인하고 .profile을 검색하십시오).


쉘 이름으로 $ 0 만 테스트 할 수 있습니까? 작동하지 않는 쉘 / 케이스가 있습니까?
Etan Reisner

마찬가지로, $-에서 i를 검사하면 대화식 쉘 테스트에 충분하지 않습니까? (그것은 tty I grant없이 대화식 쉘에서 트리거되지만 바람직하지 않은 부작용 일 수도 있고 아닐 수도 있습니다.)
Etan Reisner

@ Etan : 흠, 나는 처음 시도 $0하고 문제에 부딪쳤다는 것을 알고 있습니다 ... 나는 그들이 무엇을했는지 정확히 기억하지 못하는 것 같습니다. 콘솔에 직접 로그인 $0하면 -bash대신 표시 bash되지만 해결 될 수 있습니다.

@Etan : 예, i를 확인하는 $-것도 효과가 있습니다. tty가없는 대화식 쉘을 언제 사용해야하는지 생각해야합니까? 귀하의 솔루션은 어떤 이유로 든 더 나은 "느낌"을 가지고 있습니다.

--bash수단 "로그인 쉘"하지만 그래 당신은 당신이 값을 테스트하거나 다른 사람에게 표시 할 장소에서 그에 대한 계정에 필요합니다.
Etan Reisner

0

.bashrc 및 .profile에서 환경 변수를 소싱하여 사례 (1) 및 (2)가 해결되므로 실제 질문은 "(3) 및 (4)에 대해 동일한 변수를 소싱하는 파일의 이름은 무엇입니까?"입니다.

있을 것 같습니다 질문 askubuntu에 (내가 유니티 바탕 화면에서 가져올 환경 변수를 얻는 방법)의 일부 (3)에 대한 답변은 . / etc / X11 / Xsession에 의해 제공 될 ~ / .xsessionrc 파일을 생성 할 것을 제안합니다. (나는 이것을 시도했지만 작동하는 것 같습니다 ... 예!)

나는 아직도 무엇을 해야할지에 당황하고 있습니다 (4). 경우에 확실하게, 나는 cron 작업 (또는 데몬)를 생성, 나는 'bash는 -i -c / 빈 / foo는'올바른 환경 변수를로드 할 수 떠들썩한 파티를 사용하도록 강제로 같은 뭔가 '/ 빈 / foo는'대체 할 수 있지만, 이것은 또한 내가 대신 데몬 작업이나 크론 작업을 설치할 수있는 타사 도구를 고민해야한다는 것을 의미합니다. 수다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.