&&와 |의 차이점은 무엇입니까? bash 스크립트에서? 두 가지 다른 결과가 나타납니다. p=$(cd

아래의 두 줄을 살펴보면 두 가지 다른 결과가 나타납니다.

p=$(cd ~ && pwd) ; echo $p
p=$(cd ~ |  pwd) ; echo $p

둘은 어떻게 다릅니 까?



답변

에서 p=$(cd ~ && pwd):

  • 대체 명령 $()은 서브 쉘에서 실행됩니다.

  • cd ~디렉토리를 ~(집)으로 변경하고 , cd성공하면 ( &&) pwdSTDOUT에 디렉토리 이름 을 인쇄하므로 저장된 문자열 p은 홈 디렉토리가됩니다./home/foobar

에서 p=$(cd ~ | pwd):

  • 다시 $()서브 쉘을 생성합니다

  • |각 서브 쉘에서 실행되는 양쪽의 명령 (그리고 둘 다 동시에 시작 함)

  • 그래서 cd ~서브 쉘에서 수행하고, pwdA의 별도의 서브 쉘

  • 그래서 당신은 pwd명령을 실행하는 곳 에서 STDOUT 만 얻을 것입니다 . 이것은 상상할 수 있듯이 모든 디렉토리 일 수 있습니다. 따라서 p홈 디렉토리가 아닌 명령이 호출 된 곳의 디렉토리 이름을 포함합니다


답변

핵심 문제는 운영자 어떻게 &&하고 |두 개의 명령을 연결합니다.

&&종료 코드를 통해 명령을 연결합니다. 은 |파일 설명자 (표준 입력, 표준 출력)를 통해 두 명령을 연결합니다.

먼저 단순화하자. 과제를 제거하고 다음과 같이 쓸 수 있습니다.

echo $(cd ~ && pwd)
echo $(cd ~ | pwd)

명령 실행 서브 쉘을 제거하여이를 분석 할 수도 있습니다.

$ cd ~ && pwd
$ cd ~ | pwd

&&

명령이 실행되는 디렉토리를 표시하도록 프롬프트를 변경하면 다음과 같이 PS1='\w\$ '표시됩니다.

/tmp/user$ cd ~ && pwd
/home/user
~$ 
  • 명령 cd ~이 “현재 디렉토리”를 명령을 실행중인 실제 사용자의 홈으로 변경했습니다 ( /home/user).
  • 명령 결과 (종료 코드 0)가 성공하면 && 다음에 나오는 다음 명령이 실행됩니다.
  • 그리고 “현재 작업 디렉토리”가 인쇄됩니다.
  • 실행중인 쉘은 변경된 pwd~의 프롬프트가 표시 될 때 ~$.

어떤 이유로 디렉토리가 변경되지 않은 경우 (종료 코드가 0이 아님) (디렉토리가 존재하지 않고 권한이 디렉토리 읽기를 차단 함) 다음 명령이 실행되지 않습니다.

예:

/tmp/user$ false && pwd
/tmp/user$ _ 

종료 코드 1부터는 false다음 명령이 실행되지 않습니다.

따라서 “명령 1″의 종료 코드는 “명령 2″에 영향을줍니다.

이제 전체 명령의 효과 :

/tmp/user$ echo $(cd ~ && pwd)
/home/user
/tmp/user$ _

디렉토리가 변경되었지만 하위 쉘 내부 $(…)에서 변경된 디렉토리가 인쇄 /home/user되지만 하위 쉘이 닫히면 즉시 삭제됩니다. pwd는 초기 디렉토리 ( /tmp/user)로 돌아갑니다 .

|

이것이 일어나는 일입니다.

/tmp/user$ cd ~ | pwd
/tmp/user
/tmp/user$ _

메타 문자 |(실제 연산자가 아님)는 파이프의 각 측면에있는 각 명령 ( |)이 각각의 하위 쉘 내부에 설정되어 있는 “파이프”(bash)를 생성하도록 쉘에 신호를 보냅니다. 그런 다음 왼쪽 명령. /dev/stdin오른쪽 명령 의 입력 파일 디스크립터 ( )는 출력 디스크립터 ( /dev/stdout)에 연결되고 두 명령이 시작되어 상호 작용합니다. 왼쪽 명령 ( cd -)에는 출력이없고 오른쪽 명령 ( pwd)에는 입력이 없습니다. 따라서 각각은 자체 하위 쉘 내부에서 독립적으로 실행됩니다.

  • cd ~하나의 쉘의 비밀번호가 변경됩니다.
  • pwd다른 서브 – 쉘의 (완전 독립) PWD를 출력한다.

파이프가 끝날 때 각 쉘의 변경 사항은 무시되고 외부 서브 쉘은 pwd를 변경하지 않습니다.

이것이 두 명령이 “파일 디스크립터”에 의해서만 연결되는 이유입니다.
이 경우에는 아무것도 보내지 않으며 읽지 않습니다.

전체 명령 :

$ echo "$(cd ~ | pwd)"

명령이 실행 된 디렉토리 만 인쇄합니다.


답변

당신이 ‘|’을 의미하는지 잘 모르겠습니다 또는 ‘||’ 두 번째 경우.

‘|’ 쉘 파이프에서 한 명령의 출력을 다른 명령의 입력으로 파이프합니다. 일반적인 사용 사례는 다음과 같습니다.
curl http://abcd.com/efgh | grep ijkl
즉 명령을 실행하고 다른 명령을 사용하여 명령의 출력을 처리합니다.

예를 들어, ‘cd’는 일반적으로 출력을 생성하지 않으며 ‘pwd’는 입력을 기대하지 않으므로 무의미합니다.

‘&&’및 ‘||’ 그래도 파트너 명령입니다. 이들은 대부분의 언어에서 논리 “and”및 “or”연산자와 같은 방식으로 사용되도록 설계되었습니다. 그러나 수행되는 최적화는 쉘 프로그래밍 패러다임 인 특정 동작을 제공합니다.

논리적 “and”연산의 결과를 확인하려면 첫 번째 조건이 성공한 경우 두 번째 조건 만 평가하면됩니다. 첫 번째 조건이 실패하면 전체 결과는 항상 거짓입니다.

논리적 “또는”연산의 결과를 확인하려면 첫 번째 조건이 실패한 경우 두 번째 조건 만 평가하면됩니다. 첫 번째 조건이 성공하면 전체 결과는 항상 참입니다.

따라서 셸에서 완료된 command1 && command2 command2경우에만 실행되고 command1성공적인 결과 코드를 반환 한 경우입니다. 당신이 경우 command1 || command2 command2때 실행됩니다 command1완료되면 command1반환 오류 코드입니다.

또 다른 일반적인 패러다임은 command1테스트 명령이어야한다는 것입니다. 예를 들어 다음과 같이 한 줄 if / then 문을 생성합니다.

[ "$VAR" = "" ] && VAR="Value if empty"

변수가 현재 비어있는 경우 값을 변수에 할당하는 (긴 감기) 방법입니다.

Stack Exchange의 다른 곳에서이 프로세스를 사용하는 많은 예가 있습니다.