이와 같은 명령은 cd
디렉터리를 변경하기 위해 출력을 파이프할 수 없습니다. 명령줄 인수가 필요합니다.
에서 읽을 때 이 명령(및 , , & cd
와 같은 유사한 명령 )이 대부분의 다른 명령처럼 작동하지 않는 이유는 무엇입니까 ? 디렉토리를 변경하기 위해 표준 입력을 읽지 못하게 하는 논리는 무엇입니까?mv
cp
rm
STDIN
최고내가 찾을 수 있는 답지적했다:
cd는 외부 명령이 아닙니다. 쉘 내장 함수입니다. 외부 명령과 같이 분기/실행 컨텍스트에서 별도의 프로세스가 아닌 현재 셸의 컨텍스트에서 실행됩니다.
그러나 나에게 위의 답변은 실제로 전혀 설명하지 않습니다. cd
처리가 STDIN
에서 읽은 다른 많은 명령과 다른 이유는 무엇입니까 STDIN
?
답변1
읽기 명령은 stdin
거의 항상 텍스트 데이터 스트림을 변환된 데이터 스트림으로 변환하는 프로그램인 필터 시리즈에 속합니다.
cat
, sed
, awk
는 이러한 "필터"의 좋은 예 gzip
입니다 .sh
참조된 명령은 cp
필터 가 mv
아니며 rm
전달된 인수(이 경우 파일 또는 디렉터리)를 사용하여 작업을 수행하는 명령입니다.
이 cd
명령은 인수를 취하고(또는 제공되지 않은 경우 기본 인수를 에뮬레이트한다는 점에서) 일반적으로 아무 것도 출력하지 않지만 stdout
일부 경우(예: content 를 사용할 때)에 일부를 출력할 수 있다는 점에서 유사합니다 CDPATH
.
stdin에서 대상 디렉터리를 가져오는 변형을 생성하려는 경우에도 Bourne cd
셸의 파이프에서 사용될 때 아무런 효과가 없습니다 . 명령의 마지막 구성 요소는 하위 셸에서 실행되며 새 디렉터리에 대한 변경 사항은 현재 셸에 영향을 주지 않습니다. 예: 사용할 수 있지만 사용할 수 없음 , , , , ...dash
bash
echo /tmp | cd
ksh93
bash
dash
zsh
sh
cd <(echo /tmp)
프로세스 대체(적어도 ksh
, bash
)를 지원하는 쉘 zsh
과 함께 사용할 수 있지만cd $(echo tmp)
관심을 가질 수 있는 유일한 사용 사례는 다음과 같습니다.
echo tmp | (cd ; pwd)
마지막으로, 인수가 제공되지 않았지만 예상되는 동작이 디렉터리를 사용자의 홈 디렉터리로 변경하는 경우 또는 인수가 제공되지 않았지만 예상되는 동작이 이름을 읽는 경우를 설명하기 위해 이러한 변형이 필요합니다. stdin의 대상 디렉토리. 믿을 만한 결정 방법이 없기 때문에 이는 당연한 일입니다.
답변2
명령줄 인수는 stdin과 완전히 다릅니다. 두 가지를 모두 사용하는 명령도 일반적으로 서로 다른 목적으로 사용됩니다. 예를 들어 cat
:
echo foo bar | cat # outputs "foo bar"
cat foo bar # looks for files named "foo" and "bar", and concatenates them (if found)
stdin에서 읽는 대부분의 다른 명령을 살펴보면 비슷한 점을 발견할 수 있습니다. 즉, 인수와 stdin을 서로 바꿔서 처리하지 않고 오히려 명령에 다양한 유형의 정보를 제공하는 방법으로 처리합니다.
어느 쪽이든 동일한 유형의 정보를 얻을 수 있는 명령이 있지만 이러한 경우에도 일반적으로 어떤 명령을 사용할지 알려주는 옵션을 지정해야 합니다. 예를 들어, perl
달리 지시하지 않는 한 stdin에서 읽는 프로그램은 다음과 같습니다.
echo 'print 1' | perl # runs "print 1" as a perl program, which prints "1"
perl -e 'print 1' # runs "print 1" as a perl program, which prints "1"
perl print 1 # tries to run a file named "print" as a script, giving it the argument "1"
...그래서 질문의 전제가 잘못되었다고 생각합니다. 대부분의 명령은 인수에서 얻는 것과 동일한 종류의 정보를 표준 입력에서 얻지 못하므로 cd
그런 점에서는 드문 일이 아닙니다.