PS1이 설정되어 있는지 확인하는 목적은 무엇입니까?

PS1이 설정되어 있는지 확인하는 목적은 무엇입니까?

[ -n "$PS1" ]의 목적은 무엇입니까 [ -n "$PS1" ] && source ~/.bash_profile;? 이 줄은 .bashrc도트 파일 에 포함되어 있습니다.환매 계약.

답변1

이는 쉘이 대화형인지 확인합니다. 이 경우 ~/.bash_profile셸이 대화형인 경우에만 파일을 가져옵니다.

바라보다"이거 쉘 인터랙티브인가요?"Bash 매뉴얼에는 특정 관용구가 인용되어 있습니다. ( $-특수 변수에 이 문자가 포함되어 있는지 테스트하여 쉘이 대화형인지 확인하는 것이 i이 문제를 해결하는 더 좋은 방법이기도 합니다.)

답변2

이것은 무엇을 위한 것인가?

이는 쉘이 대화형인지 테스트하는 데 널리 사용되는 방법입니다. 다른 쉘에서는 작동하지 않고 bash에서만 작동합니다. 따라서 에 대해서는 괜찮지만(어리석다면) .bashrc에 대해서는 작동하지 않습니다 .profile( sh 로 읽으면 bash는 sh 의 가능한 구현 중 하나일 뿐이며 가장 일반적인 구현은 아닙니다).

작동하는 이유(bash에서만!)

대화형 쉘 설정쉘 변수PS1기본 프롬프트 문자열로. 따라서 쉘이 대화형인 경우 PS1(사용자가 .bashrc이를 제거하지 않는 한, 이는 아직 최상위에서 일어날 가능성이 없으며 .bashrc어리석은 일이라고 생각할 수 있습니다).

Bash에서는 그 반대가 사실입니다. Bash의 비대화형 인스턴스는 PS1시작 시 설정이 해제됩니다. 이 동작은 bash에만 해당되며 틀림없이 버그입니다( bash -c '… do stuff with $var…'is일 때 왜 작동하지 않습니까?). 그러나 bash의 모든 버전(4.4 포함)(내가 작성한 최신 버전)은 이 작업을 수행합니다.varPS1

많은 시스템이 PS1환경으로 내보내집니다. 많은 다른 쉘이 PS1다른 구문을 사용하기 때문에 이는 나쁜 생각입니다 (예:bash 프롬프트 탈출와는 완전히 다르다zsh 프롬프트 이스케이프). 그러나 이는 너무 일반적이어서 실제로 PS1설정을 보는 것은 셸이 대화형이라는 신뢰할 수 있는 표시가 아닙니다. 쉘은 PS1환경으로부터 상속될 수 있습니다.

여기서는 왜 (잘못) 사용되었나요?

.bashrc대화식으로 시작할 때 bash가 읽는 파일입니다. 잘 알려지지 않은 사실은 bash가 .bashrcis도 로그인 쉘이라고 읽는다는 것이고, 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세션의 일부로 읽을 때 bash를 실행해야 함). sh가 아닌 시작). 이 구성을 사용하면 사용자가 터미널을 열 때 환경 변수를 얻게 됩니다. 그러나 사용자는 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쉘이 비대화형일 때만 읽기——즉, 코드가 하는 일과 정반대입니다! .profilebash가 (비대화형) 로그인 쉘인 경우에는 읽으십시오. 대화형 쉘인 경우에는 읽지 마십시오.

if [[ $- != *i* && -r ~/.profile ]]; then . ~/.profile; fi

답변3

bash이 이상한 개념은 POSIX 쉘 클론으로 시작하지 않고 클론으로 Bourne Shell시작 한다는 사실 때문인 것 같습니다 .

따라서 POSIX 대화형 동작( $ENV대화형 쉘이 호출됨)이 나중에 추가되었지만 bash널리 알려지지 않았습니다.

유사한 동작을 달성하는 쉘이 있습니다. 이는 cshcsh에서 부여한 특정 값입니다 $prompt.

$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 쉘이나 POSIX 쉘에서는 작동하지 않습니다.

POSIX 셸의 경우 인증된 유일한 방법은 대화형 셸용 코드를 파일에 넣는 것입니다.

$ENV

쉘별 이름이 있습니다. 예를 들면 다음과 같습니다

$HOME/.kshrc    for the korn shell
$HOME/.bashrc   for bash
$HOME/.mkshrc   for mksh
$HOME/.shrc     for the POSIX Bourne Shell

다른 사람들은 쉘 플래그를 언급했지만 -i이는 안정적인 프로그래밍에 적합하지 않습니다. POSIX는 set -i유효할 필요도 없고 대화형 셸도 $-포함하지 않습니다 . POSIX에서는 쉘을 대화형 모드로 강제 전환 i하기만 하면 됩니다 .sh -i

변수는 $PS1환경에서 가져올 수 있으므로 비대화형 모드에서도 값을 가질 수 있습니다. 실제로 비대화형 쉘의 bash unsets는 PS1표준에 의해 부여되지 않으며 다른 쉘에서도 시행되지 않습니다.

따라서 깔끔한 프로그래밍( 를 사용하는 경우에도 bash)은 대화형 셸에 대한 명령을 에 넣는 것입니다 $HOME/.bashrc.

답변4

먼저 데비안과 우분투가 bash를 위해 설정한 것에 대해 이야기하겠습니다. 후자는 다른 시스템과 관련이 있습니다.

쉘 시작 파일 설정에 대해서는 많은 의견이 있습니다.
나도 내 의견이 있지만 올바른 설정의 기존 예를 보여 주려고 노력할 것입니다.
나는 문서의 예를 찾기 쉽기 때문에 debuan을 사용할 것입니다.
그리고 데비안을 많이 사용하기 때문에 설정 테스트도 잘 되어있고,

PS1이 설정되어 있는지 확인하는 목적은 무엇입니까?

쉘이 대화형인지 확인하기 위해서입니다.

이것/etc/profile데비안의 기본값및 우분투(/usr/share/base-files/profile에서):

if [ "${PS1-}" ]; then
    if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then

읽는 경우: 대화형(PS1 기본값)이고 bash 쉘(그러나 기본 쉘로 작동하지 않음 sh)인 경우 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(또한 루트 소유)에 영향을 주지만 bash에만 영향을 미칩니다. 그런 다음 에는 개인 설정이 있습니다 $HOME. 첫 번째 설정 ~/.profile은 대부분의 쉘 ~/.bashrc(거의 동일 ~/.bash_profile)에 적용되며 bash에만 적용됩니다.

~/.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(또는 그 반대)으로 로드될 수 있으며 이 경우 대화형 셸 확인을 사용할 수 있습니다.

관련 정보