한 명령의 경로 이름 출력을“cd”로 리디렉션 할 수없는 이유는 무엇입니까?


27

cd다른 명령에서 리디렉션 된 디렉토리 이름을 수락 하려고합니다 . 이러한 방법 중 어느 것도 작동하지 않습니다.

$ echo $HOME | cd
$ echo $HOME | xargs cd

이것은 작동합니다 :

$ cd $(echo $HOME)

첫 번째 명령 세트가 작동하지 않는 이유는 무엇입니까?


다른 사람들은 다른 방법이나 다른 방법으로 cd를 사용하여이 방법으로 실패합니까?
Didi Kohen

@DavidKohen 다른 명령을 참조
Jhonathan

주목할만한 예로는 ulimit, umask, popd, push, set, export 및 read가 있습니다.
Didi Kohen

답변:


32

cd외부 명령이 아닙니다-쉘 내장 함수입니다. 외부 명령과 달리 현재 쉘의 컨텍스트에서 실행되며 별도의 프로세스로 포크 / 실행 컨텍스트에서 실행됩니다.

셸은 cd내장 함수 를 호출하기 전에 변수와 명령 대체를 확장하여 인수로 cd값 을 받기 때문에 작동합니다 ${HOME}.

POSIX 시스템은 어떻게 바이너리가cd FreeBSD 머신에/usr/bin/cd 하지만 여러분의 생각은하지 않습니다. 바이너리를 호출하면 cd쉘 이 바이너리 를 포크 / 실행하여 실제로 작업 디렉토리를 전달한 이름으로 변경합니다. 그러나 그렇게되면 바이너리가 종료되고 분기 / 실행 프로세스가 사라지고 시작하기 전에 있던 디렉토리에있는 쉘로 돌아갑니다.


10
어느 하나 개 궁금하게 외부의 포인트 란 cd명령?
kojiro

23

cd표준 입력을 읽지 않습니다. 그렇기 때문에 첫 번째 예제가 작동하지 않습니다.

xargs명령 이름, 즉 독립 실행 파일의 이름이 필요합니다. cd쉘 내장 명령이어야하며 실행 파일 인 경우 해당 디렉토리로 변경할 수 있는지 확인하고 자동 마운트 가능한 디렉토리에 미칠 수있는 잠재적 부작용을 확인하는 것 외에는 아무런 영향을 미치지 않습니다. 이것이 두 번째 예가 효과가없는 이유입니다.


4

기존의 좋은 대답 외에도 파이프는 별도의 작업 디렉토리가있는 새로운 프로세스를 분기한다고 언급 할 가치가 있습니다. 따라서이 작업을 시도하면 작동하지 않습니다.

echo test | cd /

따라서 쉘이이 명령에서 복귀 한 후에는 / 폴더에 있지 않습니다.


그래서 다른 프로세스에서 파이프 라인 실행의 모든 명령을 a | b경우에도, a그리고 b내장되어, 적어도 다음 쉘 프로세스에서 실행되지 않는 한, 그러나 하나 보장이 없습니다. AT & T에서 예를 들어 ksh, zsh또는 bash -O lastpipe, b코드가 당신을 데려 갈 것이다, 그래서 /, 현재 쉘 프로세스가 실행됩니다.
Stéphane Chazelas

4

이미 주어진 정답 외에도 : bash를 실행하고 cd와 같은 "명령"이 무엇인지 알고 싶다면 type을 사용할 수 있습니다

$ type cd
cd is a shell builtin

또는 왜 그렇지 않은가 :

$ type time
time is a shell keyword

예를 들어 gnu 시간은 일반적으로 좋아하는 배포에 이미 포함되어 있습니다.

$ which time
/usr/bin/time

좋아요, 아이디어를 얻은 다음 도대체 유형은 무엇입니까?

$ type type
type is a shell builtin

bash 매뉴얼 스 니펫은 다음과 같습니다.

       type [-aftpP] name [name ...]
          With no options, indicate how each name would be interpreted  if  used  as  a
          command name.  If the -t option is used, type prints a string which is one of
          alias, keyword, function, builtin,  or  file  if  name  is  an  alias,  shell
          reserved word, function, builtin, or disk file, respectively.  If the name is
          not found, then nothing is printed, and an exit status of false is  returned.
          If  the -p option is used, type either returns the name of the disk file that
          would be executed if name were specified as a command  name,  or  nothing  if
          ‘‘type  -t  name’’ would not return file.  The -P option forces a PATH search
          for each name, even if ‘‘type -t name’’ would not return file.  If a  command
          is  hashed,  -p  and -P print the hashed value, not necessarily the file that
          appears first in PATH.  If the -a option is used,  type  prints  all  of  the
          places  that  contain  an  executable  named name.  This includes aliases and
          functions, if and only if the -p option is  not  also  used.   The  table  of
          hashed  commands  is  not  consulted when using -a.  The -f option suppresses
          shell function lookup, as with the command builtin.  type returns true if any
          of the arguments are found, false if none are found.

0

다른 사람들이 말했듯이 작동하지 않습니다. cd 이 외부 프로그램이 아닌 쉘 내장 명령 하지 않으므로 파이프로 연결할 수있는 표준 입력이 없습니다.

그러나 그것이 작동하더라도 파이프는 새로운 프로세스를 생성하고 첫 번째 명령의 표준 출력을 두 번째 명령의 표준 입력으로 리디렉션하므로 새 프로세스 만 현재 작업을 변경합니다 예배 규칙서; 이것은 어떤 식 으로든 첫 번째 프로세스에 영향을 미치지 못했습니다.


2
두 번째 단락이 맞습니다. 그러나 첫 번째 단락을 다시보십시오 : 왜 쉘 내장에 stdin이 없다고 가정합니까? read일반적으로 (항상?) 쉘 내장입니다. cdstdin 을 무시 하는 것은 사실 이지만 이것이 내장 된 것이 아니기 때문입니다.
dubiousjim

-2

또 다른 옵션은 하나의 명령의 표준 출력을 두 번째 명령의 명령 행 인수로 배치하는 백틱 $(...)입니다. 예를 들면 다음과 같습니다.

cd `echo $HOME`

또는 더 일반적으로;

cd `anycommand -and whatever args`

백틱의 사용은 명령을 실행하고 명령 행에서 출력을 대체하기위한 쉘에 따라 다릅니다. 대부분의 쉘이이를 지원합니다.


3
OP는 이미 자신의 질문에 따르면 $(...)효과가 있다고 언급했습니다 . 백틱을 권장하는 것은 좋지 않습니다. 백틱은 훨씬 더 복잡한 인용 규칙을 가지고 있으며 일반적으로 오류가 발생하기 쉽기 때문입니다. ( Bash Reference Manual 의 §3.5.4 "명령 대체"를 참조하십시오 .)
ruakh

$ ()는 지원되는 곳에서는 좋지만 다른 쉘과 시스템에서 백틱이 더 광범위하게 지원됩니다. 그러나 이것을 "또 다른 옵션"으로 바꿔야합니다.
Seth Noble

다른 껍질, 예; 그러나 다른 "시스템"? $(...)한 시스템에서는 지원 하지만 다른 시스템에서는 지원하지 않는 쉘이 있습니까 ?
ruakh

4
-1, 질문에 전혀 대답하지 않습니다.
Bernhard

3
@ruakh & Seth : 모든 POSIX 쉘이 지원 $(…)합니다. POSIX 쉘이없는 시스템 (즉, 정품 Bourne 쉘이있는 시스템)은 매우 오래된 시스템입니다. /bin/shBourne 쉘 /usr/xpg4/bin/sh이 있고 POSIX 쉘을 얻는 것과 같은 다른 경로가 필요한 시스템조차 오늘날에는 드 rare니다. 고대 유닉스 박스를 전문적으로 관리하지 않는 사람에게 백틱을 추천하는 것은 장애를 일으키는 것입니다.
Gilles 'SO- 악마 그만해'10
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.