이것은 몇 주 전에 여기에 게시 할 질문입니다. terdon 과 마찬가지로 a .bashrc
는 대화 형 Bash 셸에서만 제공되므로 .bashrc
대화 형 셸에서 실행 중인지 확인할 필요가 없습니다 . 혼란스럽게도, 내가 사용하는 모든 배포판 (Ubuntu, RHEL 및 Cygwin)에는 현재 셸이 대화 형인지 확인하기 위해 몇 가지 유형의 검사 (테스트 $-
또는 $PS1
)가있었습니다. 화물 컬트 프로그래밍이 마음에 들지 않으므로이 코드의 목적을 이해하기 시작했습니다 .bashrc
.
Bash는 원격 쉘을위한 특별한 경우를 가지고 있습니다
문제를 조사한 후 원격 쉘 이 다르게 취급 된다는 것을 발견했습니다 . 비 대화식 Bash 셸은 일반적으로 ~/.bashrc
시작시 명령을 실행하지 않지만 원격 셸 데몬 이 셸을 호출 하면 특별한 경우가 발생합니다 .
Bash는 원격 쉘 데몬 (일반적 rshd
으로 또는 보안 쉘 데몬)에 의해 실행될 때와 같이 표준 입력이 네트워크 연결에 연결된 상태에서 언제 실행되고 있는지 확인합니다 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
대화 형 로그인 쉘하거나 (non-interactive) 형 모드 쉘이 명령을 실행하는 데 사용되는을 시작하는 데 사용됩니다. 그러나, 문제가 될 수 있습니다 와 같은 프로그램 rcp
, scp
및 sftp
그 사용 원격 셸을 데이터를 전송.
scp
명령을 사용할 때 원격 사용자의 기본 셸 (예 : Bash)이 암시 적으로 시작된 것으로 나타났습니다 . 매뉴얼 페이지에는 이에 대한 언급이 없으며 데이터 전송에 scp
사용 되는 언급 만 ssh
있습니다. 이는 표준 출력으로 인쇄하는 명령이 포함 된 경우 .bashrc
파일 전송이 실패합니다 (예 :
scp가 오류없이 실패 함) .
15 년 전에에서이 관련 레드햇 버그 리포트를 참조 SCP 휴식을 / etc / bashrc에있는 echo 명령있다 (결국 같은 폐쇄되었다 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 "command") 사용자의 쉘을 사용하기 때문입니다. 이것은 유닉스 전통이며 다음과 같은 장점이 있습니다.
- 원격 명령이 실행될 때 사용자의 일반적인 설정 (명령 별칭, 환경 변수, umask 등)이 적용됩니다.
- 계정 셸을 / bin / false로 설정하여 계정을 사용하지 않도록 설정하는 일반적인 방법은 어떤 이유로 인증이 여전히 우연히 성공하는 경우 소유자가 명령을 실행하지 못하게합니다.
SCP 프로토콜 세부 사항
SCP가 작동하는 방법의 세부 사항에 관심이있는 사람들을 위해, 나는 흥미로운 정보를 발견 SCP가 프로토콜 작동 방법 에 대한 자세한 포함하는 원격 측에 수다 쉘 프로파일과 SCP 실행을? :
예를 들어, 이것을 원격 시스템의 쉘 프로파일에 추가하면 발생할 수 있습니다.
에코 ""
왜 그냥 걸려? 그건 어떻게하는 방식에서 오는 scp
에 소스 모드가 처음 프로토콜 메시지의 확인을 기다립니다. 이진 0이 아닌 경우 원격 문제를 알리고 새 줄이 도착할 때까지 더 많은 문자가 오류 메시지를 표시 할 때까지 기다립니다. 첫 번째 줄 이후에 다른 줄을 새로 인쇄하지 않았기 때문에 로컬 scp
은에 계속 연결되어 read(2)
있습니다. 그 동안, 쉘 프로파일이 원격 측에서 처리 된 후 scp
싱크 모드에서 시작되어 싱크 모드가 시작 read(2)
되어 데이터 전송 시작을 나타내는 2 진 0을 대기합니다.
결론 / TLDR
일반적인 문장의 대부분은 .bashrc
대화식 쉘에만 유용합니다 . rsh
또는로 원격 명령을 실행할 때는 그렇지 않습니다 ssh
. 대부분의 이러한 상황, 쉘 변수, 별칭을 설정하고 바람직하지 않은 함수를 정의에서 - 및 인쇄 텍스트 밖으로 표준을 같은 프로그램을 사용하여 파일을 전송하는 경우 적극적으로 유해 scp
하거나 sftp
. 현재 쉘이 비 대화식인지 확인한 후 종료하는 것이 가장 안전한 동작입니다 .bashrc
.