답변:
이것은 쉘이 대화식인지 아닌지를 확인하는 것입니다. 이 경우, ~/.bash_profile
쉘이 대화식 인 경우 에만 파일을 소싱하십시오 .
"이 셸이 대화 형입니까?"를 참조하십시오. bash 매뉴얼에는 특정 관용구가 인용되어 있습니다. 또한 $-
특수 변수에 i
문자 가 포함되어 있는지 테스트하여 쉘이 대화식인지 확인하는 것이 좋습니다 .이 문제에 대한 더 나은 접근 방법입니다.
bash
비 대화식 (이전 코멘트에 오타가) 버그가 IMO입니다 설정 해제의 PS1는 PS1은 그것을 해제하기 어떤 사업이없는, 떠들썩한 특정 변수가 아닙니다. 이 작업을 수행하는 유일한 쉘입니다 ( 비대화 식인 경우에도 기본값으로 yash
설정 PS1
됨).
[[ $- = *i* ]] && source ~/.bash_profile
.
[ -n "${PS1}" ]
bash 매뉴얼 $-
이 쉘이 대화 형인지 여부를 확인하기 위해 검사 를 제안 / 권장한다는 것을 강조하기 위해 여전히 대답을 업데이트했습니다. 대답 이 향상되기를 바랍니다. 건배!
이것은 쉘이 대화식인지 여부를 테스트하는 광범위한 방법입니다. bash에서만 작동하고 다른 쉘에서는 작동하지 않습니다. 그래서 (괜찮다면) 괜찮지 .bashrc
만 작동하지 않습니다 .profile
(sh로 읽히고 bash는 sh의 가능한 구현 중 하나이며 가장 일반적인 것은 아닙니다).
대화식 쉘은 쉘 변수PS1
를 기본 프롬프트 문자열로 설정합니다. 따라서 쉘이 대화 형 인 PS1
경우 설정됩니다 (사용자가 쉘 .bashrc
을 제거하지 않은 한 아직 맨 위에있을 수 없으며 .bashrc
어쨌든 할 일이 어리석은 일이라고 생각할 수 있습니다).
대화는 bash에서 참입니다. bash의 비 대화식 인스턴스는 PS1
시작할 때 설정되지 않습니다. 이 동작은 bash에만 적용되며 아마도 버그입니다 (왜 ? 가 bash -c '… do stuff with $var…'
작동하지 않습니까?). 그러나 4.4 (내가 작성한 최신 버전)까지 모든 bash 버전 이이 작업을 수행합니다.var
PS1
많은 시스템 PS1
이 환경으로 내보내 집니다. 많은 다른 포탄 사용하기 때문에 그것은 나쁜 생각 PS1
하지만 다른 구문 (예 : 배쉬의 프롬프트 이스케이프는 완전히 다른 zsh을의 프롬프트 탈출 ). 그러나 실제로 PS1
설정되어 있는 것을 보는 것은 쉘이 대화 형이라는 신뢰할만한 지표가 아니라는 것이 널리 퍼져 있습니다. 쉘은 PS1
환경에서 상속되었을 수 있습니다 .
.bashrc
bash는 시작시 대화식 일 때 읽는 파일입니다. 덜 알려진 사실은 bash도 .bashrc
로그인 쉘이며 bash의 휴리스틱은 이것이 원격 세션이라고 결론을 내립니다 (bash는 부모가 rshd
또는인지 확인 sshd
). 두 번째 경우 PS1
에는 도트 파일이 아직 실행되지 않았기 때문에 환경에서 설정 되지 않을 수 있습니다.
그러나 코드가이 정보를 사용하는 방식은 비생산적입니다.
.bash_profile
에서 실행됩니다 . 그러나 .bash_profile
로그인 시간 스크립트입니다. 세션 당 한 번만 실행되도록 의도 된 일부 프로그램을 실행할 수 있습니다. 해당 쉘을 실행하기 전에 사용자가 의도적으로 다른 값으로 설정 한 일부 환경 변수를 대체 할 수 있습니다. .bash_profile
비 로그인 셸에서 실행 하면 방해가됩니다..bash_profile
. 그러나 이것은 로딩의 경우 .bash_profile
비 대화식 로그인 쉘이 자동으로로드하지 않기 때문에 유용 할 수 /etc/profile
와 ~/.profile
.사람들이 이것을하는 이유는 GUI (일반적인 경우)를 통해 로그인하고 환경 변수 설정을 .bash_profile
대신하는 사용자를위한 것 .profile
입니다. 대부분의 GUI 로그인 메커니즘은 호출 .profile
하지만 호출 하지는 않습니다 .bash_profile
(읽기 .bash_profile
에는 sh 대신 세션 시작의 일부로 bash를 실행해야 함). 이 구성을 사용하면 사용자가 터미널을 열면 환경 변수가 나타납니다. 그러나 사용자는 GUI 응용 프로그램에서 환경 변수를 얻지 못합니다. 이는 매우 일반적인 혼란의 원인입니다. 여기서 해결책은 환경 변수를 설정 하는 .profile
대신 사용하는 것입니다 .bash_profile
. 사이에 다리를 추가 .bashrc
하고 .bash_profile
그것을 해결하는 것보다 더 많은 문제를 만듭니다.
현재 쉘이 대화 형인지 여부를 테스트하는 간단하고 이식 가능한 방법이 -i
있습니다. 옵션 이 활성화되어 있는지 테스트하십시오 .
case $- in
*i*) echo "This shell is interactive";;
*) echo "This shell is not interactive";;
esac
이에 유용 .bashrc
할 읽어 .profile
쉘이 대화 형이 아닌 경우에만 코드가 무엇의 반대, 즉 -! 읽기 .profile
배쉬는 (비 대화식) 로그인 쉘이며, 대화 형 쉘의 경우를 읽을 수없는 경우.
if [[ $- != *i* && -r ~/.profile ]]; then . ~/.profile; fi
[[ -o interactive ]]
(ksh, bash, zsh) 또는 case $- in (*i*) ...; esac
(POSIX)
PS1
대화식으로 실행하지 않으면 내 bash (버전 4.4.12)가 실제로 설정되지 않은 것 같습니다 . 테스트하기는 쉽습니다. bash 시작 파일 에 설정된 값 PS1=cuckoo bash -c '[ -n "${PS1}" ] && echo "PS1=[${PS1}]"'
을 PS1=cuckoo bash -i -c '[ -n "${PS1}" ] && echo "PS1=[${PS1}]"'
인쇄하는 동안 아무 것도 인쇄하지 않습니다 $PS1
(문자열 "cuckoo"는 인쇄하지 않음).
$-
포함 하지 않아도 i
됩니다.
[ -n "${PS1}" ]
잘못 전화하는 것이 너무 멀리 가고 있다고 말하고 싶습니다. 누군가가 PS1을 내보낼 때만 중단됩니다 (답변에서 나쁜 생각이라고 말하고 그 이유를 알 수 있습니다). 어쨌든 bash는 (쉘이 비대화 형인 경우 PS1과 PS2의 설정이 해제되어 있기 때문에.) 어쩌면 "감지 된"과 같은 단어를 사용하거나 접근의 "제한"에 대해 말하는 것이 더 좋을 것입니다. 나는 그것이 "잘못"이라고 생각하지 않습니다. PS1을 내보내는 데 문제 가 있다면 확실합니다! 어쨌든, 이것에 대해 자세히 설명해 주셔서 감사합니다.
이 이상한 개념은 bash
POSIX 셸 클론으로 시작하지 않고 복제본으로 시작한 사실에서 비롯된 것 같습니다 Bourne Shell
.
결과적으로 POSIX 대화식 동작 ( $ENV
대화식 쉘이라고 함)이 나중에 추가되었으며 bash
널리 알려지지 않았습니다.
유사한 동작을 허용하는 하나의 셸이 있습니다. 이것은 특정 값 csh
을 $prompt
가진 csh grant입니다 .
$prompt not set non-interactive shell, test $?prompt.
$prompt set but == "" .cshrc called by the which(1) command.
$prompt set and != "" normal interactive shell.
그러나 이것은 Bourne Shell이나 POSIX shell에는 적용되지 않습니다.
POSIX 쉘의 경우 부여 된 유일한 방법은 대화식 쉘의 코드를 파일에 넣는 것입니다.
$ENV
그것은 쉘 특정 이름을 가지고 있습니다. 예를 들어
$HOME/.kshrc for the korn shell
$HOME/.bashrc for bash
$HOME/.mkshrc for mksh
$HOME/.shrc for the POSIX Bourne Shell
다른 사람들은 shell flag에 대해 언급 -i
했지만 신뢰할 수있는 프로그래밍에는 사용할 수 없습니다. POSIX는 set -i
작동하지 않으며 대화식 쉘 을 $-
포함 하지도 않습니다 i
. POSIX sh -i
는 셸을 대화식 모드로 강제 실행하기 만하면 됩니다.
$PS1
환경에서 변수 를 가져올 수 있으므로 비 대화식 모드에서도 값을 가질 수 있습니다. 사실 bash
unset
의 PS1
비 대화식 쉘에서이 표준에 의해 부여되지 않은 다른 어떤 쉘에 의해 수행되지 않습니다.
따라서 깨끗한 프로그래밍은 (와도 bash
) 대화식 쉘 명령을 넣는 것 $HOME/.bashrc
입니다.
나는 데비안이 무엇인지 먼저 이야기 할 것이고, 대부분 우분투는 bash를 설정합니다. 후자는 다른 시스템에 영향을 미칩니다.
쉘 시작 파일 설정에는 많은 의견이 있습니다.
나는 또한 내 의견을 가지고 있지만 올바른 설정의 기존 예를 보여 주려고 노력할 것입니다.
파일의 예를 찾기가 매우 쉽기 때문에 debuan을 사용하겠습니다.
그리고 데비안이 많이 사용되므로 설정이 잘 테스트되었습니다.
쉘이 대화식인지 확인하십시오.
데비안 과 우분투 의 기본값/etc/profile
(/ usr / share / base-files / profile) :
if [ "${PS1-}" ]; then
if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
if 's read : if 대화식 (PS1 기본 세트)이고 bash 쉘 (기본값으로 작동하지 않음 sh
) 인 경우 PS1을 특정 새 것이 아닌 (기본이 아닌) PS1로 변경하십시오.
데비안 의 기본값/etc/bash.bashrc
에는 다음이 포함됩니다.
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
대화 형이 소스를 제공하지 않으면 (나머지)
그러나 에서이 /etc/skel/.bashrc
예이다 (사용하여 인터랙티브 셀 테스트를위한 정확한 방법은 $-
)
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
그것은 PS1의 이유와 하나의 대안을 분명히 보여 주어야합니다.
보고하는 설정은 피해야합니다.
(시스템 설정에서 () bash에 대한보다 구체적인 사용자 설정) 순서는 /etc/profile
, /etc/bash.bashrc
, ~/.profile
그리고 마지막으로 ~/.bashrc
. 이것은 ( /etc/profile
루트 소유의 ) 가장 큰 효과 (및 더 많은 셸에 대한 ) 다음에 /etc/bash.bashrc
( 루트가 소유 한) 뒤에 배치 되지만 배쉬에만 영향을 미칩니다. 그런 다음 개인 설정을 가져 오십시오. $HOME
첫 번째는 ~/.profile
대부분의 쉘 에 해당하며 bash에만 ~/.bashrc
해당됩니다 (거의 거의 동일 ~/.bash_profile
).
따라서 소스 입력 ~/.bashrc
이 잘못 ~/.profile
되었습니다. bash에 대한 특정 사용자 설정 을 더 많은 쉘에 영향을 미치는보다 일반적인 것으로 변환하고 있습니다 . 이 방법으로 수행 된 경우를 제외하고 :
# ~/.profile: executed by the command interpreter for login shells
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
bash가 실행 중인지 확인하고 해당 .bashrc
되는 경우 에만로드 합니다.
이것은 데비안에서 오는 업스트림 결정입니다. 이론적 근거는 여기에 설명되어 있습니다 .
사실, (또는 ) ~/.profile
에서의 소싱 은 특정 유스 케이스에 이미로드되어 있어야하므로 일반적인 규칙을 다시 적용하는 것입니다. 그리고 파일 소싱이 반복 될 수 있기 때문에 좋은 말이 아닙니다. 하위 디렉토리가 상위 디렉토리를로드 할 때와 마찬가지로 디렉토리 루프입니다.~/.bash_profile
~/.bashrc
그리고이 교차 소싱에서는 대화식 쉘 검사가 의미가 있습니다. 쉘이 대화식으로 ~/.bashrc
로드 된 경우에만 로드되지만 차례로로드 될 수 있으며이 ~/.profile
경우 대화식 쉘을 검사하는 것이 사용될 수 있습니다.
( export PS1='abc$ '; bash -c 'echo "[$PS1]"' )
하여 간단히 인쇄 할 수 있습니다[]
. 어떤 경우에는 ... 적어도 실험에서, 동일한 작업을 수행하지 않습니다 zsh을들이는 것 같다 의도 의이[ -n "$PS1" ]
쉘이 대화 형인지 여부를 확인하는 것입니다.