"셸 명령"(예 : mkdir / cd 콤보)을 어떻게 만들 수 있습니까?


41

디렉토리를 만들고 해당 디렉토리로 이동하는 명령을 몇 번이나 원했는지 알 수 없습니다. 기본적으로 다음과 같은 내용을 원합니다.

mkdir -p /arbitrarily/long/path; cd /arbitrarily/long/path

/arbitrarily/long/path한 번만 입력하면됩니다 .

mk-cd /arbitrarily/long/path

이를 위해 스크립트를 만들려고했지만 스크립트 내의 디렉토리 만 변경합니다. 쉘의 디렉토리도 변경하고 싶습니다.

#!/bin/bash
mkdir $1
cd $1
export PWD=$PWD

이 작업을 어떻게 수행 할 수 있습니까?


12
을 (를) 사용 cd하여 처음부터 특별한 사례를 선택했습니다. : D
Daniel B

2
내가 찾던 것이 아니라 매우 멋진 cd관련 정보 (을 사용하여 이전 디렉토리로 돌아가서 디렉토리 의 "스택"을 cd -사용 pushdpopd유지) : superuser.com/questions/324512/…
Christopher Bottoms

8
을 입력 mkdir -p /very/long/path하고 cd, 공백 을 사용한 다음 Alt + .를 눌러 마지막 인수 (예 : dir 이름)를 반복하십시오.
choroba

2
대답이 아니라 @choroba와 비슷한 주석 mkdir -p /very/long/path; cd !#:2입니다. 문자열 !#:2은 인수 nr로 확장됩니다. 2 (즉, /very/long/path세는 0부터 시작 하여 세 번째 인수 )
Ingo Blechschmidt

3
@IngoBlechschmidt는 마지막 명령의 마지막 인수이므로 사용하기 쉽습니다 !$. 역사 확장으로 할 수있는 일이 훨씬 많지만이 특정 트릭을 항상 사용합니다 .
와일드 카드

답변:


92

가장 간단한 방법은 쉘 함수를 사용하는 것입니다.

mkcd() {
    mkdir -p -- "$1" && cd -- "$1"
}

.bashrc다른 쉘 명령처럼 사용할 수 있도록 파일에 파일을 넣으십시오 .

외부 스크립트로 작동하지 않는 이유 cd는 실행중인 스크립트의 현재 디렉토리를 변경하지만 호출하는 스크립트에는 영향을 미치지 않기 때문입니다. 이것은 의도적으로 설계된 것입니다! 각 프로세스에는 자체 작업 디렉토리가 있으며 하위 디렉토리로 상속되지만 그 반대는 불가능합니다.

파이프 라인의 일부가 아닌 경우 백그라운드에서 또는 서브 쉘에서 명시 적으로 실행되지 않으면 쉘 함수는 명령이 소스 인 것처럼 별도의 프로세스에서 실행되지 않고 동일한 프로세스에서 실행됩니다. 그런 다음 기능에 의해 현재 디렉토리 쉘을 변경할 수 있습니다.

&&여기에 사용 된 첫 번째 명령이 성공하면 (수단 사용되는 두 명령을 분리하기 mkdir), 두 번째 하나를 실행 ( cd). 결과적으로 mkdir요청 된 디렉토리를 작성하지 못하면 시도하지 않아도됩니다. 오류 메시지가 인쇄되어 mkdir있습니다.

-p사용 옵션은 mkdir인수로 전달 된 디렉토리 이름의 전체 경로의 일부 누락 된 디렉토리를 생성하는이 유틸리티가 이야기하는 것입니다. 한 가지 부작용은 이미 존재하는 디렉토리를 만들도록 요청하면 mkcd함수가 실패하지 않고 해당 디렉토리에있게된다는 것입니다. 문제 또는 기능으로 간주 될 수 있습니다. 전자의 경우, 예를 들어 사용자에게 단순히 경고하는 방식으로 함수를 수정할 수 있습니다.

mkcd() {
    if [ -d "$1" ]; then
        printf "mkcd: warning, \"%s\" already exists\n" "$1"
    else
        mkdir -p "$1" 
    fi && cd "$1"
}

-p옵션이 없으면 초기 기능의 동작이 매우 달라졌을 것입니다.

작성할 디렉토리가있는 디렉토리가 존재하지 않으면 mkdir실패합니다.

작성할 디렉토리가 이미 존재하는 경우에도 mkdir실패하고 cd호출되지 않습니다.

마지막으로, PWD쉘은 이미 내부적으로 수행하기 때문에 설정 / 내보내기 는 의미가 없습니다.

편집 : --대시로 시작하는 디렉토리 이름을 허용하는 함수의 두 명령에 옵션을 추가했습니다 .


5
또한이 명령이 ~/.bashrc다른 초기화 스크립트 중 하나에 추가되지 않으면 영구적으로 사용할 수 없게됩니다 .
AFH

bash alias mk-cd 'mkdir -p \!:1; cd \!:1'에서 함수없이 tcsh와 동등한 방법을 사용할 수 있습니까? 아니면 확장 별칭과 같은 bash 함수를 생각해야합니까?
Thomas Padron-McCarthy

@ ThomasPadron-McCarthy이 csh인수 전달 메커니즘은 Bourne 스타일 별명으로 구현되지 않습니다. 기능은 실제로 훨씬 더 유연합니다.
jlliagre

@ ThomasPadron-McCarthy- 이 답변 을보고 싶을 것입니다. 별칭은에 정의 된 별칭으로 전달 된 매개 변수에 액세스하기위한 다소 모호한 메커니즘을 제공합니다 bar. 다른 옵션은 history 1in과 같이 사용하는 것 입니다 alias mk-cd='args="$(history 1)" && args="${args#*mk-cd\ }" && mkdir -p "$args" && cd'-이것은 질문자의 예에는 잘 작동하지만 동일한 줄의 다른 명령 (예 : 출력 파이프)으로 인해 실패 할 수 있으므로 일반적인 해결책은 아닙니다.
AFH

3
@ ThomasPadron-McCarthy tcsh의 별칭은 제한된 기능과 비슷하다고 생각해야합니다.
Gilles 'SO- 악마 그만'

32

대체 솔루션을 추가하고 싶습니다.

또는 명령으로 스크립트 를 호출하면 스크립트 작동합니다 ..source

. mk-cd /arbitrarily/long/path

이 작업을 수행 export하면 스크립트에서가 필요하지 않습니다. 다음 .을 사용하여 입력을 무시할 수 있습니다 alias.

alias mk-cd='. mk-cd'

이것이 작동하는 이유는 스크립트가 일반적으로 하위 셸에서 실행되어 완료시 환경이 손실되지만 .(또는 source) 명령이 현재 셸에서 실행되도록하기 때문입니다.

이 기법은 함수에 비해 너무 복잡하거나 개발 중이며 자주 편집되는 명령 시퀀스에 유용 할 수 있습니다. alias에 입력 한 후에 는 다시 .bash_aliases초기화하지 않고 원하는대로 스크립트를 편집 할 수 있습니다.

다음에주의하십시오 :-

/ 명령 으로 호출 해야하는 스크립트를 작성하는 경우이를 확인하는 두 가지 방법이 있습니다..source

  1. 어떤 이유로 든 ./로 호출 된 스크립트는 실행 source가능할 필요가 없으므로이 권한을 제거하면 스크립트가 "$ PATH"에 없거나 명시적인 경로로 호출 된 경우 권한 오류가 발생합니다.

  2. 또는 스크립트 헤드에서 다음과 같은 트릭을 사용할 수 있습니다.

bind |& read && { echo 'Must be run from "." or "source" command'; exit 1; }

이것은 하위 쉘에서 bind오류 상태는 없지만 경고를 표시 하기 때문에 작동 합니다. 따라서 read입력이 없을 때 오류를 발생시키는 데 사용됩니다.


의 정보에 감사드립니다 .. 나는 . .bashrc수많은 시간을 보냈지 만 정확히 무엇을하는지 몰랐습니다 .. 와 비슷 export합니까?
cst1992

2
@ cst1992-아니요, 명령이 완전히 다릅니다. export var내부 변수 var를 환경에 복사합니다 . 이 변수는 하위 셸에서 변수로 상속되고 가져 오지만 상위 셸에는 영향을 미치지 않습니다. 일반적으로 하위 셸은 스크립트를 실행하기 위해 만들어지며, 완료되면 내 보낸 변수를 포함하여 변경 한 내용이 손실됩니다. 스크립트가 쉘에서 변수를 설정하려면 해당 쉘에서 변수를 실행해야하며 이것이 .명령의 역할입니다. 서브 쉘을 작성하지 않고 스크립트를 실행하십시오. 흥미롭게도 스크립트 .는 실행 권한이 필요하지 않습니다.
AFH

정보에 대해서 감사드립니다. 이 정보를 귀하의 게시물에 포함시켜야한다고 주장합니다. 이것은 유용하며 솔직히 말하면 내일 거기에 올 것이라고 보장하지는 않습니다.
cst1992

@ cst1992-원래 질문에 답했지만 부수적 인 문제로 답을 어지럽히고 싶지 않습니다. .and export명령 에 대한 설명을 찾고 있다면 이 질문의 제목으로 답변을 기대할 수 없으므로 답변을 그대로 두겠습니다.하지만 귀하의 의견에 감사드립니다.
AFH

일반적으로 +1, 특히 별칭의 경우 +1 나는 소스가 필요한 스크립트를 몇 개 가지고 있으며 항상 그런 식으로 실행하는 것을 잊어 버립니다. 별명은 잘 처리합니다.
Joe

13

단일 명령은 아니지만 사용하는 모든 경로를 다시 입력 할 필요는 없습니다 !$(쉘 히스토리에서 이전 명령의 마지막 인수).

예:

mkdir -p /arbitrarily/long/path
cd !$

1

별명 을 작성하여 . 자신만의 명령을 만드는 매우 인기있는 방법입니다.

즉시 별명을 작성할 수 있습니다.

alias myalias='mkdir -p /arbitrarily/long/path; cd /arbitrarily/long/path'

그게 다야. 해당 별칭을 현재 세션뿐만 아니라 영구적으로 유지하려면 해당 명령을 도트 파일 (일반적으로 ~ / .bash_aliases 또는 ~ / .bash_profile)에 넣으십시오.


4
긴 디렉토리 이름이 하드 코딩되므로이 디렉토리가 다른 프로세스에 의해 정기적으로 파괴되지 않는 한이 별명은 유용하지 않습니다.
jlliagre

1

이미 제안 된 것 외에도 thefuck 을 추천하고 싶습니다 . 실수를 수정하여 쉘 프로세스를 간소화하기위한 Python 프레임 워크입니다. 이 트윗 에서 영감을 얻은 경우 , 기본적으로 구성된 별명을 입력하기 만하면 fuck이전 명령을 수정하려고 시도합니다. 수정 중 하나는 다음과 같이 작동합니다.

/etc $ cd somedir
bash: cd: No such file or directory
/etc $ fuck
mkdir somedir && cd somedir
/etc/somedir $ 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.