"테스트"와 /dev/null을 사용한 평가의 차이점은 무엇입니까?

"테스트"와 /dev/null을 사용한 평가의 차이점은 무엇입니까?

.sh홈브류에는 설치 여부를 확인하는 다른 스크립트가 있다는 것을 알았습니다 .

다음 구문을 사용하세요.

if test ! $(which brew); then

또 다른 하나는 다음 구문을 사용합니다.

if ! which brew > /dev/null; then

둘 다 종료 코드를 확인한다는 것을 알고 있지만 which brew둘 사이에 다른 차이점이 있는지 궁금합니다. 나에게는 전자가 더 깨끗하고 출력을 리디렉션할 필요가 없기 때문에 (아마도 잘못) 더 효율적이라고 생각합니다.

which brew또한 출력이 전송되는지 여부에 관계없이 두 번째 항목이 실제로 실행되는 이유는 무엇입니까 /dev/null? 쉘은 어떻게 작동합니까?

답변1

첫 번째는 서투른 해킹이고, 두 번째는 흔히 저지르는 실수입니다.

이 두 테스트는 완전히 다른 작업을 수행하지만 동일한 결과를 생성합니다.

if test ! $(which brew); then

이는 다음과 같은 여부를 테스트합니다.산출비 었다 which brew.

  • brew검색 경로에 있는 경우 which brew출력 단어가 생성되므로 명령은 두 개의 인수 인 path 를 test받습니다 . 두 개의 매개변수가 있는 경우 두 번째 매개변수가 비어 있으면(여기서는 그렇지 않음) 첫 번째 매개변수가 true이고, 그렇지 않으면 false입니다.!brewtest!
  • 검색 경로에 없으면 brew출력이 which brew비어 있으므로 test명령은 단일 인수를 수신 !하므로 testtrue를 반환합니다.

경로에 brew공백이 포함되어 있으면 이 명령은 오류 메시지와 실패 상태를 생성합니다.이것이 따옴표 없는 명령 대체의 의미입니다.. 여기서는 실패 상태가 원하는 결과이므로 이를 우회하는 방법입니다.

이 명령은 종료 코드를 테스트하지 않습니다 which brew. 종료 코드는 무시됩니다.

if ! which brew > /dev/null; then

이는 which brew성공 여부를 테스트하는 간단한 방법입니다. 그것은 깨지기 쉬운 어떤 것에도 의존하지 않고 그 자체에 의존합니다 which.

which brew두 경우 모두 항상 호출됩니다. 출력을 로 리디렉션하는 것이 중요한 이유는 무엇입니까 /dev/null? "이 명령의 출력 숨기기"는 "이 명령을 실행하지 않음"을 의미하지 않습니다.

brew검색 경로에서 명령을 사용할 수 없는지 테스트하는 올바른 방법은 다음과 같습니다.

if ! type brew >/dev/null 2>/dev/null; then

바라보다" which "를 사용하지 않는 이유는 무엇입니까? 그러면 무엇을 사용해야 합니까?

답변2

첫 번째 부분if test ! $(which brew); then ...

  1. 실행하면 이라는 실행 파일을 검색합니다 which brew. 발견되면 이름이 표준 출력에 인쇄됩니다. 아무 것도 발견되지 않으면 오류 메시지가 stderr에 인쇄됩니다. (일부 쉘은 내장 기능과 쉘 기능, 예약어 등을 보고하는 내장 기능을 제공합니다. 예)$PATHbrewwhichzsh
  2. $(...)잡다표준 출력(그러나 stderr은 아님) ...쉘 명령이 무엇이든 명령줄에 인수로 입력하십시오.
  3. test ! ...역방향 반환 코드가 반환되었습니다 test .... test표현을 부정하는 방법 입니다 . test ...(이 섹션에는 옵션이 없습니다 .) 이 섹션이 빈 문자열이 아닌지 ...테스트합니다 ....

결과: which이라는 실행 파일을 찾는 데 사용됩니다 brew. 생성된 경로나 빈 문자열을 명령줄에 인수로 넣고, test !인수가 빈 문자열인지 확인한 후 0(true)를 반환합니다.

두 번째 부분if ! which brew > /dev/null; then ...

여기도 which brew위와 마찬가지입니다. 실행 파일이 발견 되면 which이름을 인쇄할 뿐만 아니라 코드도 반환합니다 0(true). 아무 것도 발견되지 않으면 오류 메시지를 인쇄하고 다른 코드(오류)를 반환합니다. 이 코드는 명령 앞에 있는 !( 0-> 1, 기타 -> ) 로 인해 0쉘에 의해 반전됩니다 . 그것이 if걱정되는 것입니다. 사용자는 brew표준 출력이 which리디렉션되는 실제 경로를 보고 싶어하지 않기 때문입니다 /dev/null.

노트:

두 경우 모두 stderr은 which리디렉션되지 않으며 터미널에 표시되어야 합니다.

테스트하지는 않았지만 하나의 프로세스/내장 프로세스만 시작하기 때문에 두 번째 형식이 더 빠르다고 생각합니다. 그러나 두 명령 모두 리디렉션됩니다. 두 번째 명령은 /dev/nullwith의 출력을 캡처하여 처음에는 덜 명확하게(처음에는) 로 명시적으로 리디렉션합니다 . 대략적으로 속도를 비교할 수 있습니다.which$(...)comp내가 사용하는 기능.

which및 에 대한 매뉴얼 페이지 가 있습니다 test. 쉘의 매뉴얼 페이지( sh, ksh, bash, zsh)에는 리디렉션과 명령 대체 및 내장(그뿐만 아니라 which종종 test내장으로 구현됨)에 대한 섹션이 있습니다.

관련 정보