.txt 파일이 없으면 셸에서 * .txt를 사용한 확장이 작동하지 않습니다.


10

나는 확장과 함께 놀고 있었고, 독특한 행동을 발견했습니다. 나는 노력했다 :

echo ./*.txt

그리고 현재 디렉토리에 .txt 파일이 없습니다. 내가 얻은 결과는 다음과 같습니다.

./*.txt

나는 단지 궁금하다 : 나는 왜 이것을 얻었 는가? 나는 출력을 얻지 못할 것으로 기대했다.

추신 : .txt파일 이있을 때 확장이 올바르게 해석되었습니다. 다시 말해, 파일이 있다고 가정 smthn.txt하면 에코는 실제로 에코 current_directory/smthn.txt됩니다.

답변:


15

bash 쉘 매뉴얼 페이지에서 적응하면

bash는 각 단어에서 *,? 및 [문자를 검색합니다. 이러한 문자 중 하나가 나타나면 단어는 패턴으로 간주되고 패턴과 일치하는 알파벳순으로 정렬 된 파일 이름 목록으로 대체됩니다. 일치하는 파일 이름이없고 셸 옵션 nullglob가 활성화되어 있지 않으면 단어는 변경되지 않습니다. nullglob 옵션이 설정되어 있고 일치하는 항목이 없으면 단어가 제거됩니다.

이 경우 nullglob가 활성화되어 있지 않다고 가정하므로 단어는 변경되지 않은 상태로 유지되므로 결과가 표시됩니다.


2
다음과 같이 동작을 변경할 수 있습니다. shopt -s nullglob일치하지 않는 패턴의 경우 빈 문자열이 생성되고 shopt -u nullglob(표준 설정) 패턴 자체가 생성됩니다.
PerlDuck

13

나는 출력을 얻지 못할 것으로 기대했다.

경우 nullglob기본했다가 명령의 경우 치료 있음 (아마도 불행하게도) 공통이기 때문에, 많은 명령은 매우 예상치 않게 작동 할 것 제로 의 경우보다 질적으로 다른 방법으로 파일 이름 인수를 하나 개 이상의 파일 이름 인수.

nullglob( shopt -s nullglob)을 활성화 했고 일치하는 파일이없는 디렉토리에 있다고 가정합니다 *.txt. 그런 다음 *.txt예상대로 빈 필드가 아닌 필드가 아닌 아무것도 확장되지 않습니다. 그러나 그 결과는 다음과 같습니다.

  • ls *.txt나열합니다 모든 것을 무엇 때문에, (숨겨진 파일 제외) 현재 디렉토리에있는 파일을 ls당신이 어떤 파일 이름 인수를 전달하지 않는 경우 않습니다.
  • cat *.txt파일 이름 인수가 없을 때 마치 마치 마치 마치 마치 마치 표준 입력 에서 읽 cat습니다 cat -. 대화식으로 실행하면 입력 대기 주위에 앉아 있습니다. 많은 명령이이 방식으로 작동합니다.
  • cp *.txt dest/오류와 함께 실패합니다 cp: missing destination file operand after 'dest/'. 이것은 재앙이 아니지만 혼란스럽고 아마도 원하는 조용한 성공과는 상당히 다릅니다.
  • file *.txt파일 이름 인수가 0 인 경우 특별한 동작 이없는 다양한 다른 프로그램 은 전달되지 않으면 오류 또는 사용 메시지와 함께 계속 실패합니다.
  • 직관적으로 작동한다고 생각되는 경우조차 종종 그렇지 않습니다. 아무것도 대신 printf 'Got file: "%s"\n' *.txt인쇄 Got file: ""합니다.
  • 의 발생을 인용하는 사고 장애 *, ?그리고 [되지 않습니다 하지만 파악하기 어려울 수 있습니다 방법으로, 더 자주 분명히 잘못된 결과를 생성 할 쉘에 의해 확장하기위한 것. 현재 디렉토리에는 파일 이름으로 시작하지 않는 경우 예를 들어 gedit, 다음 apt list gedit*(여기서 apt list 'gedit*'의도) 단지가 될 것입니다 apt list및 목록 의 모든 사용 가능한 패키지.

따라서 요청하지 않고이 동작을 수행하지 않는 것이 좋습니다. 아마도 실제로 단순화 된 가장 일반적인 실제 상황 nullglob은 다음과 같습니다 for f in *.txt. 이 질문 ( Sergiy Kolodyazhnyy의 답변이 연결된) 도 참조하십시오 .

대답하기 어려운 질문은 failglob파일과 일치하지 않는 glob을 갖는 확장 오류 가있는 이유 가 bash의 기본값이 아닌 이유 입니다. Sergiy Kolodyazhnyy의 답변 은 직접 해결하지 않고도 그 이유를 포착 한다고 생각 합니다. 확장 오류를 일으키지 않고 확장되지 않는 글롭을 유지하는 것은 (아마도 불행하게도) 표준화 된 동작이며, 이는 또한 전통적이며 따라서 예상되는 동작입니다. bash는 이름으로 호출 sh되거나 --posix옵션을 전달 하지 않는 한 POSIX를 완전히 준수하려고 시도하지 않지만 POSIX 모드가 아닌 경우에도 POSIX를 직접 따르는 많은 디자인 선택이 있습니다. 그들은 어떤 행동을 취해야했고, 사용자의 기대에 반하는 것과 관련된 단점이 있습니다.


나는 이것이 역사적으로 가장 영향력이 적은 부분이라고 생각합니다. 그래서 마지막으로 저장했습니다 ...하지만 nullglob행동 에 대해 개념적으로 약간 이상한 점이 있습니다.

nullglob구문 적 으로는 일치하는 파일0 인 경우를 1, 2 또는 다른 수의 경우와 다르게 취급 하기 때문에 처음에는 우아해 보입니다 . globs가 인수로 확장되는 우리가 실행하는 명령 은 위에서 설명한 것처럼 동일하게 취급 하지 않습니다 . 그러나 구문 적으로 이것은 적어도 옳다고 느낍니다. 이것이 귀하의 질문에 대한 동기라고 생각합니다.

그러나 nullglob해결하지 못하는 또 다른 미묘한 불일치가 있습니다. 실제로 증폭됩니다. 글 로빙 문자가없는 경우 ( "와일드 카드")는 1, 2 또는 다른 숫자와 크게 다르게 취급됩니다. 예를 들어,와이 shopt -s nullglob경우, ab?d?f모든 파일과 일치하지 않습니다, 그것은 제거되고; 경우 ab?d모든 파일과 일치하지 않습니다, 그것은 제거되고; 그러나 ab일치하는 파일이없는 경우 (예 : 이름이 정확히 파일이없는 경우 ab) 여전히 제거되지 않습니다. 물론, 현재 디렉토리의 기존 파일을 전혀 참조하지 않기 때문에 제거 된 경우 재앙이 될 수 있습니다. 파일을 참조하지 않을 수도 있습니다. 그러나 이것은 여전히 ​​전체 일관성에 대한 희망을 제거합니다.

bash가 제공하는 세 가지 동작 (글로브가 아닌 것처럼 파일과 일치하지 않는 글로브를 처리하는 기본 설정, 확장되지 않은 상태로 전달), 파일을 처리 할 것으로 예상되는 동작 일치하는 파일의 모든 0을 의미하고 ( nullglob) 오류를 고려하는 안전한 동작 ( failglob)-모두 특정 단어가 의도 된 것인지 알 수없는 쉘 고유의 모호성에 대한 서로 다른 접근 방식을 나타냅니다. 파일 이름. 쉘은 호출하는 특정 명령이 인수를 처리하는 방법에 대한 지식없이 확장을 수행합니다.

이것은 많은 관심사 분리 사례 중 하나입니다 . 디자인이 유닉스 철학을 따르는 시스템에서 각 부분은 한 가지 일을하고 잘 수행하기위한 것 입니다. 쉘은 텍스트를 명령과 인수로 처리하고 대부분의 명령은 쉘 자체 외부에있는 명령을 호출합니다. 이것은 DOS와 Windows의 전통적인 명령 프로세서와 같이 외부 명령 자체가 그러한 변환을 수행하는 시스템보다 훨씬 좋고 다재다능한 경향이 있습니다 . 그러나 때때로 단점이 있습니다.


분명히 bash-4.3.39 (2)에는 없습니다 failglob. 따라서 항상 지원되는 것은 아니기 때문에 기본값으로 설정할 수 없습니다.
Ruslan

6

가장 큰 이유는이 지정한 표준 행동 때문에 POSIX - (예 : 쉘 커버가 명령어 쉘과 다른 것들의 패턴 매칭 중 표준 bash, dash- 우분투의 기본 쉘 /bin/sh, 그리고 ksh이 표준을 따라가). 2.13.3에서 파일 이름 확장에 사용되는 패턴 :

패턴이 기존 파일 이름 또는 경로 이름과 일치하지 않으면 패턴 문자열은 변경되지 않습니다.

물론 이것은 파일 이름 그대로 부작용과 일치하는 부작용이 있습니다 *.txt. nullglob에서 옵션 bashzsh캔 도움말 :이 옵션을 통해 활성화 된 경우 shopt -s nullglob일치하는 파일 이름을 찾을 수 없을 때 (그리고이 질문에 적용 기본적으로 사용되지 않습니다), 다음 globstar은 빈 문자열로 확장됩니다. ksh93동일한 효과를 달성하는 자체 고급 패턴 매칭 메커니즘~(N)*.txt

nullglob가 왜 기본이 아닌 이유 도 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.