ls * , ls ** 및 ls *** 의 결과

ls * , ls ** 및 ls *** 의 결과

이 명령을 사용하면 모든 디렉토리가 나열된다는 것을 알고 있습니다 ls. 그런데 ls *이 명령은 무엇을 하는가? 나는 이것을 사용했는데 디렉토리 만 나열합니다. 앞에 있는 별표는 ls디렉토리가 얼마나 깊게 나열되는지를 의미합니까?

답변1

ls인수로 전달된 파일 및 디렉터리의 내용을 나열하거나 인수가 제공되지 않은 경우 현재 디렉터리를 나열합니다. 동작에 영향을 미치는 일부 옵션을 전달할 수도 있습니다( man ls자세한 내용은 참고자료 참조).

ls라는 인수를 전달 하면 현재 디렉터리에서 호출된 파일이나 디렉터리를 *찾아 다른 파일이나 디렉터리와 마찬가지로 나열합니다 . 캐릭터는 다른 방식으로 취급 되지 않습니다 .*ls*

그러나 만약 ls *그것이껍데기명령줄, 즉Unix 쉘 언어로 작성된 코드, 그러면 쉘은 다음 *에 따라 확장합니다.와일드카드(또한 ~으로 알려진파일 이름 생성또는파일 이름/경로 이름 확장자)규칙.

다양한 쉘이 다양한 와일드카드 연산자를 지원하지만 대부분은 가장 간단한 연산자에 동의합니다 *. *as 패턴은 임의 개수의 문자를 나타내므로 *as는 glob패턴과 일치하는 현재 디렉터리의 파일 목록으로 확장됩니다. 한 가지 예외가 있습니다. 파일 이름의 선행 점( ) 문자는 명시적으로 일치해야 하므로 실제로는 .(어휘적으로) 로 시작하지 않는 *파일 및 디렉터리 목록 으로 확장됩니다..

예를 들어, 현재 디렉토리에 ., ...foo이라는 -l파일이 포함된 경우 셸은 이를 두 개의 인수로 확장하여 : 및 에 전달 foo bar하므로 다음 과 같이 입력합니다.*ls-lfoo bar

ls -l "foo bar"

또는

'ls' "-l" foo\ bar

동일한 명령을 실행하는 세 가지 방법이 있습니다. 세 가지 경우 모두, ls명령(언급된 디렉토리 조회 /bin/ls에서 $PATH)에는 "ls", "-l" 및 "foo bar"라는 세 가지 매개변수가 전달됩니다.

그건 그렇고, 이 경우 ls첫 번째 (엄격히 말하면두번째) 하나는 옵션으로 제공됩니다.

이제 제가 말했듯이, 쉘마다 와일드카드가 다릅니다. 수십 년 전에 연산자 1이 zsh도입되었으며 모든 수준의 하위 디렉터리와 일치하도록 의도되었습니다. 이는 and의 약어 로 , 디렉터리 하강 시 심볼릭 링크를 따른다는 점만 제외하면 동일합니다.**/(*/)#***/

몇 년 전(2003년 7월 ksh93o+) ksh93이 동작을 복제하기로 결정했지만 선택 사항으로 만들고 사례만 다루기로 결정했습니다 **(그렇지 않았습니다 ***). 또한 **alone은 ²에서 특별하지 않지만(다른 전통적인 쉘에서와 동일한 의미를 가집니다 zsh. 왜냐하면 이는 임의의 수의 문자 뒤에 임의의 수의 문자가 오는 것을 의미하기 때문입니다) ksh93에서는 (따라서 현재의 모든 항목과 동일한 의미를 가집니다) 디렉토리) 파일 또는 디렉토리)는 동일합니다. 1개(숨겨진 파일 제외)³.*******/*

bashksh93몇 년 후(2009년 2월, bash 4.0), 동일한 구문으로 복사되었지만 한 가지 불행한 차이점이 있습니다. bash는 s **와 유사합니다 . 즉, 하위 디렉터리로 반복할 때 심볼릭 링크를 따르지만 일반적으로 그렇지 않습니다. 원하지만 불쾌한 부작용이 있을 수 있습니다. bash-4.3에서는 심볼릭 링크를 계속 따르지만 재귀는 거기서 멈추기 때문에 부분적으로 수정되었습니다. 5.0에서 완전히 수정되었습니다.zsh***

yash**2008년 버전 2.0에 추가되었으며 extended-glob옵션을 통해 활성화되었습니다. 그 구현은 zsh그 자체로 특별하지 않다는 점에서 's 에 더 가깝습니다 **. 버전 2.15(2009)에서는 ***in zsh과 두 가지 자체 확장 기능을 추가했으며 반복 시 숨겨진 디렉터리를 포함합니다( .**in ,.***zshD 글로벌 예선(예 **/*(D): 숨겨진 파일 및 디렉터리가 고려되지만 숨겨진 파일을 확장하지 않고 숨겨진 디렉터리만 탐색하려면 ((*|.*)/)#*또는 이 필요합니다 **/[^.]*(D)).

물고기또한 지원됩니다 **. 이전 버전과 마찬가지로 bash디렉토리 트리가 내려갈 때 심볼릭 링크를 따릅니다. 그러나 해당 쉘에서는 **/*동일하지 않습니다 **. **여러 디렉터리에 걸쳐 있을 수 있는 확장이 더 많습니다 . *여기서 일치 fish하지만 일치하지 않는 반면, 일치하며 예를 들어 and로 작성해야 합니다 . 거기에는 다음과 같은 내용이 따르는 것으로 이해됩니다.**/*.ca/b/c.ca.ca**.ca.cab/c/d.czsh**/.*{,**/}.*********

tcshV6.17.01(2010년 5월)에도 옵션이 추가되었으며 및 à la 에 대한 globstar지원이 추가 되었습니다 .*****zsh

따라서 in tcsh, bashand ksh93, (해당 옵션( globstar)이 활성화된 경우) or 는 fish현재 **파일 및 디렉터리 아래의 모든 파일과 디렉터리를 확장하며 ***for 와 동일하고 with 로 심볼릭 링크를 통과하며 in 및 와 동일합니다. (비록 이러한 미래 버전의 쉘은 기호 링크를 통과할 수도 있습니다).**fish**tcshglobstar*bashksh93

위에서는 어떤 확장도 옵션으로 해석되지 않도록 해야 함을 알 수 있습니다. 이렇게 하려면 다음을 수행합니다.

ls -- *

또는:

ls ./*

일부 파일 이름도 특별하게 취급될 수 있으므로 ls두 번째 명령이 더 바람직한 일부 명령(중요하지 않은 경우)이 있습니다 . 이는 이 문자를 포함하는 대부분의 텍스트 유틸리티 및 파일 이름의 경우입니다 . 모든 인수 앞에 추가하면 해당 인수의 특별한 의미가 제거됩니다(적어도 위의 경우에는).---cdpushd=awk./

$FIGNORE또한 대부분의 쉘에는 와일드카드의 동작에 영향을 미치는 많은 옵션 이 있다는 점에 유의해야 합니다(예: 도트 파일 무시 여부, 정렬 순서, 불일치가 있는 경우 수행할 작업...).ksh

csh또한 tcsh, 및 if를 제외한 fish모든 쉘에서zsh와일드카드 패턴일치하는 파일이 없으며 패턴이 확장되지 않은 인수로 전달되므로 혼란과 오류가 발생할 수 있습니다. 예를 들어, 현재 디렉터리에 숨겨지지 않은 파일이 없는 경우

ls *

실제로는 두 개의 매개변수 와 ls함께 호출됩니다 . 파일이 전혀 없고 전화하는 사람도 없기 때문에 오류 메시지가 표시됩니다.ls**엘에스(쉘이 아님) like: 는 사람들이 실제로 영역을 확장하고 있다고 ls: cannot access *: No such file or directory생각하게 만드는 것으로 알려져 있습니다 .ls

다음과 같은 경우 문제가 더욱 심각해집니다.

rm -- *.[ab]

현재 디렉토리에 nor 파일이 없으면 *.a실수로 호출된 파일(,,)이 삭제될 수 있으며 이로 인해 보고됩니다.*.b*.[ab]cshtcshzsh불일치오류가 발생하여 호출되지 않습니다 rm( 와일드카드는 fish지원되지 않음 [...]).

*에 리터럴을 전달하려면 or 또는 와 같은 방식으로 문자를 인용 ls해야 합니다 . POSIX와 유사한 쉘에서는 또는를 사용하여 와일드카드를 완전히 비활성화할 수 있습니다 (후자는 / 에뮬레이션을 제외하고는 효과가 없습니다 ).*ls \*ls '*'ls "*"set -o noglobset -fzshshksh


1 항상 지원되었지만 처음에는 zsh-2.0(그리고 아마도 그 이전)에서 (*/)#인력이 부족했고 , 그 다음에는 2.1에서, 그 다음에는 2.2(1992년 초)에서 최종 형태로 나타났습니다...../****/**/

²의globstarshort옵션**, 각각 및 대신 및 를 사용할 수 있도록 나중에 추가되었습니다(2015).*****/****/*

³ 다음도 참조하세요ksh93 디자인 globstar에도 이상한 점이 있습니다, 그 중 일부는 복사되었습니다 bash. .

답변2

명령의 ls기본값은 다음과 같습니다 ls ..현재 디렉터리의 모든 항목 나열.

이 명령은 ls *"쉘 모드에서 확장에 대해 ls 실행 *" 을 의미합니다.

*패턴은 셸에 의해 처리되며 로 시작하는 항목을 제외한 현재 디렉터리의 모든 항목으로 확장됩니다 ..

이중 모드 또는 삼중 모드의 해석은 *사용되는 실제 쉘에 따라 다릅니다.

*0개 이상의 문자와 일치하는 와일드카드 문자입니다. 일부 현대 쉘은 **이 패턴을 볼 때 하위 디렉토리로 반복됩니다.

답변3

echols명령이 확장되는 이유를 확인하기 위해 먼저 입력하는 대신 입력하여 전체 프로세스를 쉽게 이해할 수 있습니다 .

$ echo *
Applications Downloads Documents tmp.html

따라서 이 경우에는 ls *다음으로 확장됩니다.ls Applications Downloads Documents tmp.html

$ echo **
Applications Downloads Documents tmp.html

$ echo ***
Applications Downloads Documents tmp.html

그래서 아무것도 변하지 않았습니다. 이는 bash대부분의 사람들이 사용하는 쉘을 사용하고 있다고 가정 하며 다른 쉘은 다르게 작동합니다. ashor csh또는 kshor 를 사용하면 zsh상황이 달라질 것으로 예상할 수 있습니다. 그것이 다른 껍질을 갖는 요점입니다.

따라서 globbing ( ) 연산자가 우리를 위해 무엇을 할 수 있는지 bash이해하기 위해 다른 것을 시도해 보겠습니다(여전히 를 사용하고 있음 ). *예를 들어 이름의 일부를 기준으로 필터링할 수 있습니다.

$ echo D*
Downloads Documents

흥미롭게도 후행 슬래시는 모든 디렉터리 이름의 암시적인 부분입니다. 따라서 */디렉터리(및 디렉터리에 대한 심볼릭 링크)만 생성됩니다.

$ echo */
Applications/ Downloads/ Documents/

슬래시를 중간에 배치하여 여러 수준의 필터링을 수행할 수 있습니다.

$ echo D*/*/
Documents/Work/ /Documents/unfinished/

디렉터리 Downloads에는 하위 디렉터리가 포함되어 있지 않으므로 출력에 표시되지 않습니다. 필요한 파일만 확인하는데 유용합니다. 나는 다음과 같은 명령을 사용해 왔습니다.

$ ls -l /home/*/public_html/wp-config.php

wp-config.php여기에는 사용자 디렉터리(있는 경우)의 기본 수준에 존재하는 모든 파일이 나열됩니다 public_html. 아니면 더 완벽할 수도 있습니다.

$ find /home/*/public_html/ -name wp-config.php

wp-config.php이렇게 하면 모든 사용자 디렉터리나 그 하위 디렉터리 public_html에서 모든 파일을 찾을 수 있지만 find /home/ -name wp-config.php아무것도 확인하지 않을 뿐만 아니라 더 효율적으로 실행됩니다.하지만public_html각 사용자의 디렉터리입니다.

답변4

"더 자세히" 알고 싶다면 ls -R(재귀) 옵션을 사용하거나 다음과 같이 find를 사용하세요.

find . -ls

"find"는 디렉터리 트리의 맨 아래까지 드릴다운하며("ls -R"과 유사) 디렉터리 나열(-type d), 파일만 표시(-type f), 추가 항목이 있는 파일 표시 등 더 많은 옵션을 제공합니다. 콘텐츠 파일 특성(/etc/passwd에 사용자 없음, 특정 권한 등) "찾기"는 스크립팅에서도 더 안전합니다(쉘 간의 일관되지 않은 와일드카드 규칙, 대시를 사용한 파일의 특수 이스케이프 등으로 인해).

쉘 와일드카드 와일드카드는 도트 파일에서 별표 "*"와 함께 사용할 수 없습니다. 도트 파일만 나열하려면 다음을 사용하십시오.

ls .??*

관련 정보