Bash: "설정"이 내가 예상한 대로 작동하지 않는 이유는 무엇입니까?

Bash: "설정"이 내가 예상한 대로 작동하지 않는 이유는 무엇입니까?

내보낸 변수의 값만 Mac OS .bash_profileX를 통해 PATH 변수에 추가되는 것을 확인했습니다. 그러나 변수 값을 로컬로 설정하는 것은 그렇지 않습니다. 지역 변수를 경로에 추가할 수 없는 이유는 무엇입니까?


"뭔가 잘못 이해한 것 같은데, 헷갈리는 코드를 게시해 보세요. — Giles 어제."

이 스니펫을 고려하여 MONGODB 변수를 다음과 같이 설정했습니다.

set MONGODB="/usr/local/mongodb/bin"    
export PATH=${PATH}:${MONGODB}

나는 source .bash_profile터미널에 있습니다. 다음 에코가 표시됩니다.

PATH=~/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:

그러나 대신 MONGODB를 내보내고 내 것을 얻으면 .bash_profile다음과 같은 에코가 표시됩니다.

PATH=~/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/local/mongodb/bin

아마도 set부적절한 사용일까요?

답변1

set MONGODB="/usr/local/mongodb/bin"

이것은 변수 할당이 아닙니다. (C 쉘(csh, tcsh) 중 하나이지만 Bourne 스타일 쉘(sh, ash, bash, ksh, zsh 등) 중 하나는 아닙니다.) 이는 내장 함수에 대한 호출입니다 set. 위치 인수를 설정합니다(예 $1: $2대기). 그런 다음 터미널에서 이 명령을 실행해 보십시오 echo $1.

쉘 변수에 값을 할당하려면 다음을 작성하십시오.

MONGODB="/usr/local/mongodb/bin"

이렇게 하면 사용할 수 있는 셸 변수(이름이 지정된 매개변수라고도 함)가 생성됩니다 $MONGODB. 변수는 .export를 사용하여 내보내지 않는 한 셸 내부에 유지됩니다 export MONGODB. 내보낸 경우 변수는 다음을 통해 이 셸에서 시작된 모든 프로세스에도 표시됩니다.환경. 작업과 내보내기를 한 줄로 압축할 수 있습니다.

export MONGODB="/usr/local/mongodb/bin"

MONGODB현재 수행 중인 작업의 경우 스크립트 외부에 있을 필요는 없으며 PATH이미 내보내졌습니다(변수를 내보낸 후 새 값을 할당하면 환경에 반영됩니다). 따라서 다음과 같이 작성할 수 있습니다.

MONGODB="/usr/local/mongodb/bin"    
PATH=${PATH}:${MONGODB}

답변2

쉘 변수가 어떻게 작동하는지 설명하려고 합니다. PATH와 같은 환경 변수에 로컬 변수를 추가하는 것은 절대적으로 가능합니다.

실행 중인 각 프로세스에는 환경 변수 목록이 있습니다. 이름=값 쌍입니다. 새로운 프로세스를 생성할 때십자가()이는 이러한 변수(열린 파일, 사용자 ID 등과 같은 다른 변수도 포함)를 상속합니다. 대조적으로, 쉘 변수는 내부 쉘 개념입니다. 새 프로세스를 생성할 때 상속되지 않습니다. 쉘 변수를 내보내고 환경 변수로 설정할 수 있습니다. 쉘 스크립트를 작성할 때 FOO='bar'이는 쉘 변수입니다. 2개의 스크립트를 만들어 볼 수 있습니다:

# test1.sh
FOO='bar'
sh test2.sh

# test2.sh
echo "${FOO}"

첫 번째 스크립트를 실행하면 내부 쉘 변수를 설정한 다음 fork()를 호출합니다. 상위 쉘 프로세스는기다리다()하위 프로세스를 종료한 다음 실행을 계속합니다(명령이 더 있는 경우). 자식 프로세스에서구현하다()새 쉘을 로드하기 위해 호출됩니다. 이 새로운 프로세스는 FOO에 대해 알지 못합니다. 첫 번째 스크립트를 수정하는 경우:

# test1.sh
export FOO='bar'
sh test2.sh

FOO 변수는 환경의 일부가 되며 포크된 프로세스에 상속됩니다. 환경은 전역적이지 않다는 점에 유의하는 것이 중요합니다. 하위 프로세스는 상위 프로세스의 환경 변수에 영향을 미칠 수 없습니다.

# test3.sh
sh test4.sh
echo "${PATH}"

# test4.sh
export PATH="${PATH}:/new/path"

test4.sh의 수정 사항은 test3.sh에 표시되지 않습니다. 전혀 그렇지 않습니다. 하위 프로세스가 종료되면 해당 환경은 삭제됩니다. test3.sh를 변경해 보겠습니다.

# test3.sh
source test4.sh
echo "${PATH}"

소스는 내장된 쉘 명령입니다. 이는 쉘에게 파일을 연 다음 해당 내용을 읽고 실행하도록 지시합니다. 쉘 프로세스는 하나만 있습니다. 이렇게 하면 호출자는 환경 변수는 물론 쉘 변수까지 수정된 내용을 볼 수 있습니다.

PATH는 쉘에게 다른 실행 파일을 찾을 수 있는 위치를 알려주는 특수 환경 변수라는 것을 알고 계실 것입니다. 새 로그인 셸이 시작되면 자동으로 .bash_profile을 얻습니다. 거기에 선언된 변수가 표시됩니다. 그러나 .bash_profile에서 sh를 사용하여 다른 스크립트를 호출하면 해당 스크립트에 설정한 PATH가 손실됩니다.

답변3

어쩌면 "set"을 사용하는 것이 부적절할까요?

예, 그게 당신 문제입니다. set예상한 대로 수행되지 않습니다. ~에서문서:

이 내장 함수는 매우 복잡하며 별도의 섹션이 필요합니다. set쉘 옵션의 값을 변경하고 위치 매개변수를 설정하거나 쉘 변수의 이름과 값을 표시할 수 있습니다.

"실제로 쉘 변수 설정"이 수행하는 작업 목록에서 눈에 띄게 누락되었습니다. 모든 문서에 묻혀 있으면 그것이 쉘을 설정하는 것임을 알 수 있습니다.위치 매개변수당신이 주장한 것에 대해. 당신은 단지 주장만 하면 됩니다 MONGODB="/usr/local/mongodb/bin". 따라서 $1해당 값으로 설정됩니다( $#매개변수가 하나만 있으므로 1로 설정됩니다).

니모닉 방지 Unix 명령 이름은 1점이죠?

어쨌든 한번 시도해 보세요.

MONGODB=/usr/local/mongodb/bin
export PATH=${PATH}:${MONGODB}

작동합니다.

관련 정보