내 아치 설치에는 다음 줄이 /etc/bash.bashrc
있습니다 ./etc/skel/.bashrc
# If not running interactively, don't do anything
[[ $- != *i* ]] && return
데비안에는 /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
그러나 에 따르면 man bash
비대화형 쉘은 다음 파일도 읽지 않습니다.
예를 들어,
bash
비대화형으로 실행될 때 쉘 스크립트를 실행하려면 환경에서 변수를 찾고BASH_ENV
, 해당 변수가 환경에 있으면 그 값을 확장하고, 확장된 값을 읽을 파일 이름으로 사용하고, 이름. Bash는 다음 명령이 실행된 것처럼 동작합니다.if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
그러나 변수 값은PATH
파일 이름을 검색하는 데 사용되지 않습니다.
내가 올바르게 이해했다면 *.bashrc
이 파일은 해당 파일을 가리키도록 설정된 경우에만 읽혀집니다. BASH_ENV
이는 우연히 일어날 수 없는 일이며, 누군가 그에 따라 변수를 명시적으로 설정한 경우에만 발생합니다.
.bashrc
이는 사용자 피드를 자동으로 가져오는 스크립트를 설정하는 가능성을 깨뜨리는 것으로 보이며 BASH_ENV
이는 유용할 수 있습니다. bash는 명시적으로 지시하지 않는 한 비대화식으로 실행될 때 이러한 파일을 절대 읽지 않는다는 점을 감안할 때 기본 *bashrc
파일이 이를 허용하지 않는 이유는 무엇입니까?
답변1
이것은 제가 몇 주 전에 여기에 게시하려고 했던 질문입니다. 좋다테든, 나는 대화형 Bash 쉘에서만 발생한다는 것을 알고 있으므로 대화형 쉘에서 실행 중인지 확인할 .bashrc
필요가 없습니다 . .bashrc
혼란스럽게도,모두내가 사용하고 있는 배포판(Ubuntu, RHEL 및 Cygwin)은 현재 셸이 대화형인지 확인하기 위해 일종의 검사(테스트 $-
또는 )를 수행합니다. $PS1
나는 좋아하지 않는다화물 숭배 프로그래밍그래서 나는 내 것을 이해하기 시작했습니다 .bashrc
.
Bash에는 원격 쉘을 위한 특별한 경우가 있습니다.
이 문제를 조사한 후 발견했습니다.원격 쉘다르게 대우받습니다. 비대화형 Bash 쉘은 일반적으로 ~/.bashrc
시작 시 명령을 실행하지 않지만 쉘이 시작될 때 특별한 상황이 발생합니다.원격 쉘 데몬에 의해 호출됨:
rshd
Bash는 원격 쉘 데몬(보통 ) 또는 보안 쉘 데몬 에 의해 실행될 때와 같이 네트워크 연결에 연결된 표준 입력으로 실행 중인지 확인하려고 합니다sshd
. Bash가 이런 방식으로 실행 중이라고 판단하면 ~/.bashrc(파일이 존재하고 읽을 수 있는 경우)에서 명령을 읽고 실행합니다. 로 호출하면 이 작업을 수행하지 않습니다sh
.--norc
옵션을 사용하여 이 동작을 억제할 수 있고--rcfile
옵션을 사용하여 다른 파일을 강제로 읽을 수 있지만 일반적으로 쉘은 이러한 옵션rshd
으로 호출되지 않거나sshd
지정이 허용되지 않습니다.
예
원격 시작 부분에 다음을 삽입하십시오 .bashrc
. ( 또는 .bashrc
에서 시작된 경우 테스트하는 동안 이 기능이 일시적으로 비활성화됩니다.).profile
.bash_profile
echo bashrc
fun()
{
echo functions work
}
다음 명령을 로컬로 실행합니다.
$ ssh remote_host 'echo $- $0'
bashrc
hBc bash
- 아니요
i
는$-
쉘이비대화형. - 소개가 없으면 쉘이 아님
-
을 나타냅니다 .$0
로그인 쉘.
원격으로 정의된 셸 기능 .bashrc
도 실행할 수 있습니다.
$ ssh remote_host fun
bashrc
functions work
나는 ~/.bashrc
그것이었다는 것을 알아차렸다.오직명령이 인수로 지정될 때 획득됩니다 ssh
. 이는 의미가 있습니다: ssh
일반 로그인 셸을 시작 .profile
하거나 .bash_profile
실행하는 데 사용되는 경우( .bashrc
이러한 파일 중 하나가 명시적으로 이를 수행하는 경우에만 소스를 가져옵니다).
.bashrc
(비대화형) 원격 명령을 실행할 때 소스를 사용하면 얻을 수 있는 주요 이점은 셸 기능을 실행할 수 있다는 것입니다. 그러나 일반 명령의 대부분은 .bashrc
대화형 셸에서만 관련됩니다. 예를 들어 셸이 대화형이 아니면 별칭은 확장되지 않습니다.
원격 파일 전송이 실패할 수 있음
rsh
ssh
이는 대화형 로그인 셸을 시작하거나 비대화형 셸을 사용하여 명령을 실행하는 경우 일반적으로 문제가 되지 않습니다. 그러나 그것은문제가 될 수 있습니다rcp
다음 과 같은 scp
프로그램 의 경우sftp
원격 쉘데이터를 전송하는 데 사용됩니다.
scp
해당 명령을 사용할 때 원격 사용자의 기본 셸(예: Bash)이 암시적으로 시작되는 것으로 나타났습니다 . 매뉴얼 페이지에는 이에 대한 언급이 없습니다. 단지 scp
데이터 전송을 위한 목적일 뿐입니다. ssh
이것의 결과는 다음과 같습니다.bashrc
표준 출력으로 인쇄하는 명령이 포함되어 있으면 파일 전송이 실패합니다.,예를 들어,
오류 없이 scp가 실패함.
15년 전 관련 Red Hat 버그 보고서도 참조하세요./etc/bashrc에 echo 명령이 있으면 scp가 중단됩니다.(결국 폐쇄됨 WONTFIX
).
왜 실패 scp
했는가sftp
SCP(보안 사본)그리고SFTP(보안 파일 전송 프로토콜)로컬 및 원격 측에는 전송되는 파일에 대한 정보를 교환하기 위한 자체 프로토콜이 있습니다. 원격 측의 예상치 못한 텍스트는 프로토콜의 일부로 (잘못) 해석되어 전송이 실패합니다. 에 따르면달팽이 책 FAQ
그러나 사람이 쉽게 읽을 수 있도록 로그인 시 텍스트 메시지를 출력하는 명령문(예 : , , 등 ) 이 서버의 시스템 또는 사용자별 셸 시작 파일(
.bashrc
, , 등)에 자주 발생합니다 ..profile
/etc/csh.cshrc
.login
fortune
echo "Hi there!"
표준 입력에 추가되면 이러한 코드는 대화형 로그인에서만 출력을 생성해야 합니다
tty
. 이 테스트를 수행하지 않으면 이러한 텍스트 메시지가 속하지 않는 곳에 삽입됩니다. 이 경우scp2
/ 와sftp
사이의 프로토콜 흐름을 오염시킵니다sftp-server
.쉘 시작 파일은 다음과 같은 이유로 관련이 있습니다.
sshd
사용자를 대신하여 프로그램을 시작할 때 사용자의 셸을 사용합니다. (예: /bin/sh -c "명령"을 사용하십시오). 이는 Unix 전통이며 다음과 같은 장점이 있습니다.
- 사용자의 공통 설정(명령 별칭, 환경 변수, umask 등)은 원격 명령이 실행될 때 적용됩니다.
- 어떤 이유로 인해 인증이 여전히 예기치 않게 성공하는 경우 /bin/false로 설정하여 계정의 셸을 비활성화하는 일반적인 관행에 따라 소유자는 어떤 명령도 실행할 수 없습니다.
SCP 프로토콜 세부정보
SCP 작동 방식에 대한 자세한 내용에 관심이 있는 분들을 위해 다음에서 흥미로운 정보를 찾았습니다.SCP 프로토콜의 작동 방식세부정보가 포함된원격 측에서 세션 셸 프로필을 사용하여 scp를 실행할 수 있나요?:
예를 들어 원격 시스템의 셸 구성 파일에 다음을 추가하면 이런 일이 발생할 수 있습니다.
에코""
왜 그냥 멈춰있나요? 이것은
scp
어떻게에서 비롯됩니다원천모드는 첫 번째 프로토콜 메시지의 승인을 기다립니다. 바이너리 0이 아니면 이를 원격 문제에 대한 알림으로 간주하고 새 줄이 도착할 때까지 더 많은 문자가 오류 메시지를 형성할 때까지 기다립니다. 첫 번째 줄 이후에 다른 줄을 인쇄하지 않기 때문에 로컬 파일이scp
루프에 갇혀 에서 차단됩니다read(2)
. 한편 원격 측에서 셸 프로필이 처리된 후scp
수신자 모드가 시작되며 이 모드도 에서 차단됩니다.read(2)
, 데이터 전송 시작을 나타내는 이진수 0을 기다리고 있습니다.
결론/TLDR
일반 명령문의 대부분은 .bashrc
대화형 셸에만 유용합니다. rsh
원격 명령을 사용하거나 실행할 때는 효과가 없습니다 ssh
. 대부분의 경우 쉘 변수, 별칭을 설정하고 함수를 정의할 필요가 없습니다.모든 텍스트scp
또는 같은 프로그램을 사용하여 파일을 전송하는 경우 표준 출력은 매우 해로울 수 있습니다 sftp
. 현재 쉘이 비대화형인지 확인한 후 종료하십시오 .bashrc
.
답변2
매뉴얼 페이지에는 다음과 같은 비대화형 원격 쉘에 대한 bash
소스가 언급되어 있지 않습니다..bashrc
ssh hostname command
http://git.savannah.gnu.org/cgit/bash.git/tree/shell.c#n1010
COMMAND EXECUTE BASHRC
--------------------------------
bash -c foo NO
bash foo NO
foo NO
rsh machine ls YES (for rsh, which calls 'bash -c')
rsh machine foo YES (for shell started by rsh) NO (for foo!)
echo ls | bash NO
login NO
bash YES
http://git.savannah.gnu.org/cgit/bash.git/tree/shell.c#n1050
/* If we were run by sshd or we think we were run by rshd, execute
~/.bashrc if we are a top-level shell. */
if ((run_by_ssh || isnetconn (fileno (stdin))) && shell_level < 2)
{
maybe_execute_file (SYS_BASHRC, 1);
maybe_execute_file (bashrc_file, 1);
답변3
관례적으로 .bashrc
이는 사용자가 셸에 대한 사용자 정의 구성을 저장하는 곳입니다.
이러한 사용자 정의 구성은 환경 변수, 별칭 및 멋진 프롬프트일 수 있습니다. 비대화형 쉘의 경우 이러한 누락된 항목은 의미가 없습니다. 또한 비대화형 셸은 다양한 상황에서 호출될 수 있으며 이러한 환경 변수가 거짓 부정 또는 보안 취약점으로 이어질 수 있는지 확실하지 않습니다.
가장 가까운 예는 다음과 같은 별칭입니다.
alias cp='cp -i'
그러면 비대화형 쉘이 영원히 정지됩니다.
.bashrc
따라서 문제가 발생하지 않도록 상단에서 점검이 수행됩니다 .
쉘은 비대화형이라고 할 수 있기 때문에로그인쉘이므로 *bashrc
소스를 명시적으로 차단할 필요가 없습니다.
껍질이 있을 때비대화형 로그인 쉘이라고 함, 소스인 경우 소스는 /etc/profile
, 및에서 발견된 첫 번째 소스입니다.~/.bash_profile
~/.bash_login
~/.profile
bash가 대화형 로그인 셸로 호출되면,또는 --login 옵션을 사용하여 비대화형 쉘로 사용, 먼저 /etc/profile 파일(파일이 존재하는 경우)에서 명령을 읽고 실행합니다. 파일을 읽은 후 ~/.bash_profile, ~/.bash_login, ~/.profile을 순서대로 찾아 존재하고 읽을 수 있는 첫 번째 파일부터 명령을 읽고 실행합니다.
.bashrc
이러한 파일이 스스로 가져오는 것을 막을 수 있는 방법은 없으므로 내부적으로 확인하는 것이 .bashrc
더 안전하고 작업을 단순하게 유지합니다.