이 명령을 실행할 때 Gnu/Linux는 실제로 무엇을 하고 있나요?
cd; ls /Bin/g* &> /dev/null; echo $?
최종 출력은 0입니다.
답변1
g
해당 문자로 시작하는 이름이 디렉토리에 있는지 확인하는 것이 목적이라면 쉘 /Bin
에 더 나은 접근 방식이 있습니다 .bash
shopt -s nullglob
set -- /Bin/g*
if [ "$#" -ne 0 ]; then
printf 'There are %d names starting with "g" in /Bin\n' "$#"
echo 'These are those names:'
printf '\t%s\n' "$@"
else
echo 'No names in /Bin start with "g"'
fi
실행중인 시스템에 있다고 가정하면 bash
...
0
패턴과 일치하는 이름이 있고 패턴과 일치하는 이름이 없거나 일부 디렉터리 권한이 이를 허용하지 않는 경우 명령 세트는 /Bin/g*
0이 아닌 값(아마도 2
0이 아닐 수도 있음) 을 출력합니다. )이 출력되어 목록을 생성합니다.1
ls
우선 시작하는 것은 cd
흥미롭지 않으며 아마도 필요하지 않을 것입니다(이 명령을 제거하면 영향을 미치는 상황은 매우 인위적입니다). 현재 디렉터리를 임의의 값으로 변경하거나, 설정되지 않은 경우 (또는 동등한 데이터베이스) $HOME
에서 /etc/passwd
정의한 홈 디렉터리 로 변경합니다.HOME
명령을 실행하기 전에 ls
쉘은 /Bin/g*
패턴을 일치하는 이름 목록으로 확장합니다. 디렉토리 목록을 읽을 수 있는 권한이 있고 /Bin
디렉토리 /Bin
에 문자로 시작하는 이름이 있는 g
경우 해당 이름 목록이 에 대한 인수인 패턴을 대체합니다 ls
. 일치하는 항목이 없거나 올바른 액세스 권한이 없으면 /Bin
패턴은 그대로 유지됩니다.
실행되면 ls
쉘 확장에 의해 제공된 인수 목록을 가져와 /Bin/g*
해당 이름을 나열하려고 시도합니다. 이러한 이름이 존재하고 귀하에게 어떤 이름이든 나열할 권한이 있다는 점을 고려하면하위 디렉토리/Bin
문자 로 시작하는 g
명령은 ls
결국 성공적으로 종료되고 종료 상태를 반환합니다 0
. 이름이 이렇다면아니요존재하거나 이름 중 하나가 나열할 권한이 없는 하위 디렉터리를 참조하는 경우 0이 아닌 종료 상태로 실패합니다(이 경우 GNU에서 반환됨 ls
).2
이는 쉘 &>/dev/null
에서 표준 출력 및 표준 오류 스트림을 로 리디렉션하는 리디렉션입니다 . 실행 시 이는 명령의 모든 출력과 모든 오류가 삭제됨을 의미합니다( 기록된 특수 장치 파일입니다. 모든 데이터가 삭제됨). 들어갈 때). 리디렉션 연산자는 표준이 아니며 "표준 출력을 로 리디렉션한 다음 표준 오류를 표준 출력이 있는 위치로 리디렉션합니다"라고 쓰는 것이 더 좋습니다. 기술적으로 이 단계는 셸이 와일드카드 패턴을 확장하기 전에도 발생합니다.bash
/dev/null
ls
/dev/null
&>
>/dev/null 2>&1
/dev/null
/Bin/g*
마지막으로 echo $?
가장 최근 종료 상태를 출력합니다. 이는 종료 상태 ls
(또는 스키마 확장 실패로 인해 발생한 오류 코드 또는 /Bin/g*
찾을 수 없거나 전혀 실행되지 않아 발생한 오류 코드일 수 있음, 아래 참조) 입니다 .ls
$PATH
이에 영향을 미치는 두 가지 셸 옵션이 있습니다.
이 옵션이 현재 쉘 세션에서 설정 되면
nullglob
모드/Bin/g*
는 다음과 같습니다.완전히 제거유지되기보다는. 이는ls
인수 없이 실행되고 목록이 표시됨을 의미합니다.현재의디렉토리(홈 디렉토리가 될 수 있음cd
). 현재 디렉터리를 읽을 수 있는 권한이 있으면 이 작업이 성공합니다. 디렉터리 내용을 읽을 수 있는 권한이 없으면ls
0이 아닌 종료 상태가 반환됩니다(이 경우 GNUls
가 반환됩니다).1
쉘 옵션이 설정되어 있고
failglob
패턴과 일치하는 이름이/Bin/*
없으면껍데기불평할 것이고no match: /Bin/g*
0이 아닌 종료 상태를 얻게 될 것입니다(아마도 전혀 실행되지 않을 것1
입니다 ).ls
오류 메시지를 생성하는 것은 쉘이고 쉘의 표준 오류 스트림은 다음과 같습니다.아니요이 오류 메시지는 최종 인쇄 전에 터미널에 인쇄됩니다
/dev/null
(이는 리디렉션된 출력 스트림일 뿐이며ls
이 경우 실행되지 않음을 기억하세요) .ls
echo $?
1
쉘 변수는 다음에 영향을 미칩니다.
이 변수는 쉘이 인용되지 않은 값을 확장할 때 적용됩니다
IFS
. 이것이echo $?
마지막 단계( )에서 수행하는 작업입니다. 쉘이$?
올바른 값으로 호출되도록 확장되면 먼저echo
문자를 구분 기호로 사용하여 값을 단어로 분할합니다.$IFS
기본적으로$IFS
이는 공백, 탭 및 줄 바꿈입니다.IFS
문자열로 설정 하면 (012
GNU를 사용하는 경우 가능한 값임) 쉘은 값(의 종료 상태)을 빈 문자열로 분할합니다(값이 구분 기호 분할로 처리되기 때문입니다). 인수 없이 호출되면 출력으로 단일 개행 문자가 생성됩니다.$?
bash
ls
$?
ls
echo
이러한 불행한 상황을 방지하려면 다음을 사용할 수 있습니다
echo "$?"
(큰따옴표 참고$?
).
포함되지 않습니다:
PATH
ls
에 없으면 어떤 일이 발생하고 발생하지 않는지 , 그리고 이것이 및 에$PATH
영향을 미치지 않는 이유는 무엇입니까 ?cd
echo
- 실제로 명령을 실행하는 것과 관련된 모든 것,
fork
+exec
등. - 별칭은 도구의 셸 기능 또는 을 확장하거나 재정의합니다
cd
.ls
echo
- 쉘이 아닌
bash
곳에서는 어떤 일이 발생 하며 그 이유는 무엇입니까? - 효과
set -f
.