.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입니다.!
brew
test
!
- 검색 경로에 없으면
brew
출력이which brew
비어 있으므로test
명령은 단일 인수를 수신!
하므로test
true를 반환합니다.
경로에 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
답변2
첫 번째 부분if test ! $(which brew); then ...
- 실행하면 이라는 실행 파일을 검색합니다
which brew
. 발견되면 이름이 표준 출력에 인쇄됩니다. 아무 것도 발견되지 않으면 오류 메시지가 stderr에 인쇄됩니다. (일부 쉘은 내장 기능과 쉘 기능, 예약어 등을 보고하는 내장 기능을 제공합니다. 예)$PATH
brew
which
zsh
$(...)
잡다표준 출력(그러나 stderr은 아님)...
쉘 명령이 무엇이든 명령줄에 인수로 입력하십시오.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/null
with의 출력을 캡처하여 처음에는 덜 명확하게(처음에는) 로 명시적으로 리디렉션합니다 . 대략적으로 속도를 비교할 수 있습니다.which
$(...)
comp
내가 사용하는 기능.
which
및 에 대한 매뉴얼 페이지 가 있습니다 test
. 쉘의 매뉴얼 페이지( sh
, ksh
, bash
, zsh
)에는 리디렉션과 명령 대체 및 내장(그뿐만 아니라 which
종종 test
내장으로 구현됨)에 대한 섹션이 있습니다.