&&

&&

두 가지 다른 결과를 제공하는 아래 두 줄을 살펴보겠습니다.

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

둘 사이의 차이점은 무엇입니까?

답변1

존재하다 p=$(cd ~ && pwd):

  • 명령 대체, $()서브셸에서 실행

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

존재하다 p=$(cd ~ | pwd):

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

  • 양쪽의 명령은 |자체 서브셸에서 실행됩니다(둘 다 동시에 시작됩니다).

  • 이는 서브쉘 에서 cd ~수행되며pwd분리서브쉘

  • pwd따라서 명령을 실행한 위치의 STDOUT만 가져올 수 있습니다. 이는 상상할 수 있는 모든 디렉터리일 수 있으므로 p홈 디렉터리가 아닌 명령이 호출된 디렉터리의 이름을 포함합니다.

답변2

핵심 문제는 연산자를 두 명령 &&에 연결하는 방법입니다.|

종료 코드로 명령을 연결합니다 &&. |파일 설명자(stdin, stdout)를 통해 두 명령을 연결합니다.

먼저 단순화해 보겠습니다. 할당을 제거하고 다음과 같이 작성할 수 있습니다.

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다음 명령의 실행을 방지합니다.

따라서 "Command 1"의 종료 코드는 "Command 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 변경 사항이 없습니다.

이것이 바로 이 두 명령이 "파일 설명자"를 통해서만 연결되는 이유입니다.
이 경우 아무 것도 전송되지 않고 아무것도 읽혀지지 않습니다.

전체 명령은 다음과 같습니다.

$ echo "$(cd ~ | pwd)"

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

답변3

두 번째 경우에는 "|"을 의미하는지 잘 모르겠습니다.

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

제시한 예에서 "cd"는 일반적으로 출력을 생성하지 않는 반면 "pwd"는 입력을 필요로 하지 않기 때문에 이것은 다소 의미가 없습니다.

'&&' 및 '||'는 파트너 명령에 지나지 않습니다. 논리 AND 및 OR 연산자가 대부분의 언어에서 사용되는 것과 동일한 방식으로 설계되었습니다. 그러나 수행된 최적화는 특정 동작, 즉 쉘 프로그래밍 패러다임을 제공합니다.

논리적 AND 연산의 결과를 확인하려면 첫 번째 조건이 성공하면 두 번째 조건을 평가하기만 하면 됩니다. 첫 번째 조건이 실패하면 전체 결과는 항상 false가 됩니다.

논리적 OR 연산의 결과를 확인하려면 첫 번째 조건이 실패할 때 두 번째 조건을 평가하면 됩니다. 첫 번째 조건이 성공하면 전체 결과는 항상 true가 됩니다.

따라서 셸에서는 완료되어 성공적인 결과 코드를 반환하는 경우 command1 && command2 command2에만 실행됩니다 . command1있는 경우 command1 || command2 command2완료 시 실행되며 command1, command1그렇다면 실패 코드를 반환합니다.

또 다른 일반적인 예는 command1테스트 명령입니다. 이는 단일 줄의 if/then 문을 생성합니다. 예를 들면 다음과 같습니다.

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

이는 변수가 현재 비어 있는 경우 변수에 값을 할당하는 (장황한) 방법입니다.

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

관련 정보