쉘 스크립트에서 .bashrc를 성공적으로 소싱 할 수 없습니다


51

일반적 ~/.bashrc으로이 명령을 사용하여 파일을 소싱 할 수 있습니다

source ~/.bashrc

그러나 이것을 쉘 스크립트로 작성하고 실행하면 아무 일도 일어나지 않습니다. 왜?
이것을 할 수있는 방법이 있습니까?

내 스크립트 :

#!/bin/bash
chmod a+x ~/.bashrc
source ~/.bashrc

또한 .대신 (도트)를 시도했습니다 source. 같은 결과입니다.

답변:


26

쉘 스크립트는 자체 쉘 인스턴스에서 실행됩니다. 모든 변수 설정, 함수 정의 등은이 인스턴스 (및 자식)에만 영향을 주지만 호출 쉘에는 영향을 미치지 않으므로 스크립트가 끝난 후에 사라집니다.

반대로 source명령은 새 셸 인스턴스를 시작하지 않지만 현재 셸을 사용하므로 변경 사항이 유지됩니다.

.bashrc를 읽을 수있는 바로 가기를 원한다면 쉘 스크립트 대신 쉘 함수 또는 별칭을 사용하십시오.

alias brc='source ~/.bashrc'

빠른 답변 감사합니다. 귀하의 솔루션은 효과가 있지만 'aliac brc = ....'행을 저장하려면 bashrc 파일을 수동으로 편집해야합니다. 환경 변수를 변경하는 GUI를 개발하려고합니다. 따라서 다른 컴퓨터의 bashrc 파일을 수동으로 편집 할 수 없습니다.
shantanu

1
source ~/.bashrc환경을 변경하려는 쉘에서 실행 해야합니다. 다른 프로세스에서 변경할 수 없습니다. 어쩌면 (전역 적으로)이 별명을 추가하는 것은 GUI 설치 프로세스의 일부일 수 있습니다.
Florian Diesch

1
그래서 스크립트에 별칭 명령을 일찍 넣은 다음 .bashrc를 소스로 만들거나 별칭 파일을 어딘가에 넣어야 할 때 brc를 호출합니까?
user137717

내가 한 일은 Florian Diesch의 답변이 연장 된 것입니다. 여러 줄 별칭을 사용할 수 있습니다. alias brc = 'chmod a + x ~ / .bashrc; source ~ / .bashrc '나는 여전히 꽤 새롭기 때문에 이것이'나쁜 연습 '으로 간주되는지 확실하지 않습니다. 그래도 작동합니다.
A_user_apps는

13

당신은 .bashrc일반적으로 시작한다 :

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

스크립트에는 PS1이 설정되어 있지 않기 때문에 (대화식이 아니기 때문에) 일찍 종료되기 때문에 경로를 재설정하지 않습니다. 시연하려면 스크립트를 수정하십시오.

    #!/bin/bash
    chmod a+x ~/.bashrc
    PS1='$ '
    source ~/.bashrc

이것은 이제 스크립트가 새로운 작업을 수행 할 수있게합니다 .bashrc. 참고 : 스크립트가 종료되면 env는 스크립트를 시작하기 전의 상태로 설정됩니다. 다음에 터미널을 시작할 때 변경 사항이 반영됩니다.


적어도 16.04 이후 그리고 아마도 그 이전에는 기본 우분투 .bashrc가 더 안정적인 방법을 사용하여 쉘이 대화식인지 확인합니다. /etc/bash.bashrc여전히 PS1 테스트가 있습니다.
잔나

12

시험:

exec bash

~ / .bashrc, ~ / .bash_aliases 등을 다시로드해야합니다.


9
이것은 현재 bash 프로세스를 새로운 것으로 바꿉니다. 사용하는 것보다 훨씬 짧거나 쉽지는 source않지만 변수를 파괴하여 사용자가 수동으로 설정 한 값을 원할 수도 있습니다.
Florian Diesch

bashrc 소싱 후 다른 명령을 사용하여 셸 스크립트의 컨텍스트에서 유지하십시오. 그 후에 새 bash 상태가 필요한 명령을 넣으십시오. 이후 exec bash명령을 이해하는 방식은 여전히 ​​이전과 동일한 bash 설정에 있습니까?
tatsu

11

라비의 답변 을 보완하고 싶습니다 .

기본 ~/.bashrc파일은 Ubuntu 18.04와 같은 단락으로 시작 하므로이 동작은 Ubuntu (및 아마도 가장 파생 된 배포판)에만 해당됩니다 .

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

비 대화식 쉘에서 파일이 실행중인 경우 파일 평가가 중지됩니다. 이는 모든 스크립트가 비 대화식 쉘에서 실행 되므로 이후 source에이 속성을 상속하는 모든 파일 이기 때문에 스크립트의 경우입니다 .

eval 파헤 치다, 난도질하다

내가 사용, 특히 우분투를 해결하기 위해 못생긴 해킹을 발견 eval대신 source:

eval "$(cat ~/.bashrc | tail -n +10)"

단순히 첫 번째 몇 줄을 건너 뛰고 ~/.bashrc나머지는 평가하여 나머지는 평가하고 현재 실행을 수정합니다.

그것은 마법 번호이며 우분투 버전에서는 작동하지 않을 수 있습니다. 그러나 알려진 시스템에 대한 스크립트를 작성하는 경우 좋은 솔루션이 될 수 있습니다.

더 환상적인 솔루션은 정규식을 사용하여 평가를 중지하는 특정 비트를 대상으로 할 수 있습니다.

Shebang 대안

일부 시나리오에서 더 잘 작동하는 또 다른 대안은 shebang에 플래그를 추가하여 스크립트가 대화식 쉘에서 실행되도록하는 것입니다 .

#!/bin/bash -i

몇 가지 사항에 유의하십시오.


2

이 튜토리얼 덕분에 다음 을 사용하는 것을 발견 할 때까지 다른 방법 중 어느 것도 나를 위해 일하지 않았습니다 ( source /path/to/filevs . ./path/to/file, alias 등 ...) .

#!/usr/bin/env bash 오두막

더 간단한 #!/usr/bin/env것 대신에 인수가 인터프리터에게 전달되도록하는데, 여기에서 핵심이라고 생각합니다 . 자세한 내용은 이 문서 를 참조하십시오.

어쨌든 어떤 형태의 소스 명령이 작동하지 않으면 shebang을 확인하십시오. 문제가 될 수 있습니다 :)

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