쉘 스크립트에서“cd”가 작동하지 않는 이유는 무엇입니까?


43

그냥 내 디렉토리변경 하는 스크립트를 작성하고 싶습니다 .

파일에 아래 명령을 넣었습니다. /home/alex/pathABC

#!/bin/sh
cd /home/alex/Documents/A/B/C
echo HelloWorld

나는했다 chmod +x pathABC.

터미널에서에있는 동안 /home/alex나는 실행 ./pathABC하지만 출력은 그대로 HelloWorld이며 현재 디렉토리는 변경되지 않습니다.

그래서 무엇이 잘못 되었습니까?


답변:


74

다른 사람들이 설명했듯이 디렉토리는 스크립트가 호출되는 터미널 프로세스가 아니라 스크립트의 자식 프로세스에서 변경됩니다. 자식 프로세스가 종료되면 터미널은 원래 있던 터미널로 돌아갑니다.

몇 가지 대안 :

1. 심볼릭 링크

집에 쉽게 접근하고자하는 긴 경로로 심볼릭 링크를 연결하십시오

$ ln -s /home/alex/Documents/A/B/C ~/pathABC

다음을 사용하여 디렉토리에 액세스하십시오.

$ cd ~/pathABC

2. 별명

~ / .bashrc에 별명을 넣으십시오.

alias pathABC="cd /home/alex/Documents/A/B/C"

( 여기에서 )

3. 기능

디렉토리를 변경하는 함수를 작성하면 함수는 터미널 프로세스에서 실행 된 다음 디렉토리를 변경할 수 있습니다.

( 여기에서 )

4. 어린이로 달리지 마십시오

스크립트를 실행하지 말고 소싱하십시오. 소싱 ( .또는 수행 source)은 스크립트가 자체 서브 쉘에서 실행되는 대신 동일한 쉘에서 실행되도록합니다.

$ . ./pathABC

( 여기 에서 여기로 )

5. CD 가능 변수

에서 cdable_vars옵션을 설정하고 ~/.bashrc디렉토리에 환경 변수를 작성 하십시오 .

shopt -s cdable_vars
export pathABC="/home/alex/Documents/A/B/C"

그런 다음 사용할 수 있습니다 cd pathABC

( 여기에서 )


15
이제 나는 사용법을 이해한다 source! 나는 왜 내가 왜 그렇게하지 source .bashrc않았 는지 궁금해했다bash .bashrc
hytromo

옵션 3은 훌륭하게 작동했습니다. 방금 스크립트 시작 부분에 go_to_wherever () {cd my / directory} 함수를 정의했습니다. 해당 디렉토리에서 조작을 실행하기 전에 호출했습니다.
i2097i 2019 년

> 5. cd-able vars-그렇지 cd $pathABC않습니까?
loxaxs

7

터미널에서 스크립트를 실행하면 하위 프로세스가 실행됩니다. 이 하위 프로그램에서, 즉 스크립트는 지정된 디렉토리로 변경됩니다. 그러나 부모 프로세스에서, 즉 스크립트를 실행하는 위치는 여전히 이전 경로에 있습니다. 또는 단순히 우리는 말할 수 있습니다 :

The scope of cd command is only for child process not parent


2
여기에 추가, 당신이 찾고있는 효과를 얻을 @ 알렉스 스크립트를 실행 를 소싱하여 부모 프로세스 : 중 . pathABC또는 source pathABC.
zwets

4

당신은 사고 오류를 만들고 있습니다. 현재 이 동일한 디렉토리에있는 동안 스크립트 는 새 디렉토리로 이동했습니다.

디렉토리 에 다른 스크립트를 작성 하고 디렉토리가 변경된 후 스크립트에서 실행하면 다음을 알 수 있습니다.

#!/bin/sh
cd /home/alex/Documents/A/B/C && ./another_script.sh # (if it is executable)

두 번째 스크립트는 새 디렉토리에서 실행됩니다.

HelloWorld 

그냥 스크립트의 출력입니다.


3
HelloWorld는 상위 쉘로 "반환"되지 않고 표준 출력으로 출력됩니다.
Mog

pwd상황에 완전히 새로운 스크립트를 추가하는 대신 새 디렉토리에서 실행하면 더 명확해질 수 있습니다 .
wjandrea

0

hello world는 단순한 추적 설명이므로 다음을 시도해 보겠습니다.

다음을 cd.sh포함하는 bash 스크립트 파일 을 작성하십시오 .

#!/bin/bash
echo "/home/mike/Documents/A/B/C"
  • .sh확장 bash는 스크립트를주는 이전 협약 연장는 파일 이름입니다. 순전히 화장품이며 일반적으로 불필요합니다. 그러나이 경우 핵심 cd명령 과 구별하는 것이 중요합니다 .

다음을 사용하여 bash 스크립트 파일을 실행 가능으로 표시하십시오.

chmod a+x cd.sh

이제 파일을 실행하십시오.

$ cd $(./cd.sh)
bash: cd: /home/alex/Documents/A/B/C: No such file or directory
  • cd 우리 모두는 알고있다.
  • $(...) 괄호 안에 명령을 실행하고 출력을 반환합니다.
  • cd.sh경로에 있다면 경로를 지정할 필요가 없습니다. ./명령을 지정하기 위해 접두사가 현재 디렉토리에 있습니다.
  • 스크립트 의 echo출력은을 cd.sh통해 부모에게 다시 전송됩니다 $(...). 부모 (우리의 쉘 프롬프트)는이 출력을 사용하여 Linux cd명령으로 전달합니다 .

다른 사람들이 언급했듯이 자식 프로세스는 부모의 디렉토리를 변경할 수 없습니다. 이것은 자녀가 과정이 끝난 후 어디로 가야하는지 부모에게 말할 수있는 한 가지 방법입니다.


@wjandrea 전화로 코딩하면 얻을 수있는 것입니다! 방금 집에 돌아와서 고칠 게요 감사. 음 방금 확인했는데 제대로 작동합니다. 아마 14.04한 시간 전에 읽은 버전일까요?
WinEunuuchs2Unix

글쎄, 당신은 완전히 스크립트를 변경했습니다. 이전에는 cd /home/mike/Documents/A/B/C출력을 생성하지 않은 명령 하나였습니다 . 이제는 echo "/home/mike/Documents/A/B/C"출력을 생성합니다.
wjandrea

@wjandrea 사실, 나는 또한 스크립트를 호출하는 방식을 완전히 바꿨다. 단순한 ./cd.sh것이 cd $(./cd.sh)아니라 지금 은 부모의 현재 디렉토리를 변경하는 자식의 목표를 달성합니다. 예, 그것은 틀에 박힌 것이지만 사람들이 흥미를 느끼기를 희망하는 또 다른 방법입니다.
WinEunuuchs2Unix 1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.