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


86

명령 ls을 사용하면 모든 디렉토리가 나열됩니다. 그러나 ls *명령은 무엇을합니까? 나는 그것을 사용했고 단지 디렉토리를 나열했다. 앞에있는 별 ls은 디렉토리를 얼마나 깊이 나열 할 수 있습니까?

답변:


155

ls전달 된 디렉토리의 파일과 내용을 인수로 나열하고, 인수가 없으면 현재 디렉토리를 나열합니다. 또한 동작에 영향을주는 여러 옵션을 전달할 수도 있습니다 ( man ls자세한 내용 참조).

경우 ls라는 인수를 전달되는 *, 그것은라는 파일이나 디렉토리를 찾습니다 *현재 디렉토리와는 다른 모든처럼 나열합니다. 캐릭터를 다른 방식으로 ls취급하지 않습니다 *.

그러나 경우 ls *A는 커맨드 라인은 쉘이 확장되며, *해당 셀에있어서의 로빙은 (이라고도 파일명 생성 또는 파일명 확장 규칙).

다른 쉘은 다른 globbing 연산자를 지원하지만 대부분은 가장 간단한 연산자에 동의합니다 *. *그래서 패턴으로, 문자의 수를 의미 *A가 아니라 glob그 패턴과 일치하는 현재 디렉토리에있는 파일 목록에 확장됩니다. 그러나 .파일 이름 의 맨 앞에있는 점 ( ) 문자를 명시 적으로 일치 시켜야 한다는 점에서 예외 가 있으므로 *실제로 .사전 식으로 시작하지 않는 파일 및 디렉토리 목록으로 확장됩니다 .

현재 디렉토리라는 파일이 포함 된 경우 예를 들어, ., .., .foo, -lfoo bar, *에 전달할 두 개의 인수에 쉘에 의해 확장됩니다 ls: -l그리고 foo bar당신이 입력 한 것처럼 될 것입니다, 그래서 :

ls -l "foo bar"

또는

'ls' "-l" foo\ bar

정확히 같은 명령을 실행하는 세 가지 방법이 있습니다. 세 가지 경우 모두, ls명령 (에 /bin/ls언급 된 디렉토리 조회에서 실행될 $PATH것임)에는 "ls", "-l"및 "foo bar"라는 세 가지 인수가 전달됩니다.

또한이 경우 ls첫 번째 (엄격하게 말하기 두 번째 ) 옵션을 옵션으로 취급합니다.

내가 말했듯이, 다른 쉘은 다른 globbing 연산자를 가지고 있습니다. 몇 년 전, zsh도입 **/짧게, 서브 디렉토리의 모든 수준에 맞게 의미 operator¹을 (*/)#하고 ***/디렉토리를 하강하면서 심볼릭 링크를 다음 것을 제외하고는 동일하다.

몇 년 전 (2003 년 7 월 ksh93o+), ksh93그 행동을 모방하기로 결정했지만 선택적으로하기로 결정했고 **사건 만 다루었 다 (아닌 ***). 또한 ksh93 **에서 단독으로 특별하지는 않지만 zsh( *다른 전통적인 쉘에서 와 동일하게 의미가 있기 때문에 **임의의 문자 수와 문자 수를 **의미하므로) 현재와 같은 **/*파일 또는 디렉토리 와 동일 (숨겨진 파일 제외).

bash복사 ksh93몇 년 후 (2009 월 배쉬 4.0) 동일한 구문하지만 불행한 차이 : bash는의가 **같았다 zsh***하위 디렉토리로 재귀 할 때 당신이 그것을 어떻게 원하는 것을 일반적으로하지 않은 심볼릭 링크를 따라했다, 즉되고 불쾌한 부작용이있을 수 있습니다. bash-4.3에서는 심볼릭 링크가 여전히 따랐다는 점에서 부분적으로 수정되었지만 재귀는 거기서 멈췄습니다. 5.0에서 완전히 수정되었습니다.

yash**extended-glob옵션을 사용하면 2008 년 버전 2.0에 추가 되었습니다 . 그것의 구현은 혼자가 특별하지 않다는 zsh점에서 더 가깝습니다 **. 버전 2.15 (2009 년)에서는 추가 ***같은에서 zsh자체 확장이 : .**.***(에서 재귀 때 숨겨진 DIRS을 포함하는 zshD 글로브 규정 에서와 같이이 ( **/*(D)하지만) 숨김 파일 및 디렉토리를 고려할 것입니다 만 숨겨진 통과하려면 숨겨진 파일은 확장 할 수 없지만 ((*|.*)/)#*또는 **/[^.]*(D)) 가 필요합니다 .

물고기 쉘 도 지원합니다 **. 의 이전 버전과 마찬가지로 bash디렉토리 트리를 내릴 때 심볼릭 링크를 따릅니다. 그러나 그 쉘에서는와는 **/*다릅니다 **. **더 확장되어 *여러 디렉토리에 걸쳐있을 수 있습니다. 에서 fish, **/*.c일치 a/b/c.c하지만 a.c반면, a**.c일치 a.cab/c/d.czsh**/.*예를 들어 서면되어야한다 .* **/.*. 그곳 ***으로 이해 **이어 *지도록 동일 **.

tcsh또한 globstarV6.17.01 (2010 년 5 월)에 옵션이 추가 **되었으며 ***à la를 모두 지원합니다 zsh.

그래서에서 tcsh, bash그리고 ksh93(해당 옵션이 활성화 된 경우 ( globstar)) 또는 fish, **현재의 아래의 모든 파일과 디렉토리를 확장하고, ***과 동일 **위한 fish횡단 심볼릭 링크, **위해 tcshglobstar,와 같은 *에서 bashksh93그것의 비록 ( 미래 버전의 해당 쉘이 심볼릭 링크를 통과한다는 것은 불가능하지 않습니다).

위에서는 확장이 옵션으로 해석되지 않았는지 확인해야합니다. 이를 위해 다음을 수행하십시오.

ls -- *

또는:

ls ./*

일부 파일 이름을 사용 ls하더라도 --특수하게 처리 될 수 있기 때문에 두 번째 명령이 선호되는 명령은 중요하지 않습니다 . 이 경우의 -대부분의 텍스트 유틸리티, cdpushd포함 된 파일 이름과 =에 대한 문자를 awk예를 들어 있습니다. ./모든 인수 앞에 추가 하면 특별한 의미가 제거됩니다 (적어도 위에서 언급 한 경우).

또한 대부분의 쉘은 또한 참조 (일치 존재하지 않는 경우는 어떻게 해야할지, 정렬 순서를 점 파일을 무시할지 여부를 싫든, ...)이 글 로빙 동작에 영향을주는 옵션을 가지고 있음을 주목해야한다 $FIGNORE매개 변수ksh

또한, 모든 쉘에 있지만 csh, tcsh, fishzsh경우, 글 로빙 패턴이 어떤 파일과 일치하지 않습니다, 패턴이 혼란 가능성이 버그를 일으키는 확장되지 않은 인수로 전달됩니다. 예를 들어 현재 디렉토리에 숨겨지지 않은 파일이없는 경우

ls *

실제로 호출 ls두 개의 인수 ls*. 거기에 어떤 파일이 전혀 없다, 그래서 아무도 호출되지로서 그리고 *하나, 당신은에서 오류 메시지가 나타납니다 LS : 같은 (셸이 아닌) ls: cannot access *: No such file or directory사람들이 그것이라고 생각하는 것으로 알려져있다, ls즉 실제로 globs의 확대되었다.

다음과 같은 경우 문제가 더욱 악화됩니다.

rm -- *.[ab]

더 있다면 *.a*.b현재 디렉토리에 파일을, 당신은라는 파일 삭제 끝낼 없습니다 수도 *.[ab]실수를 ( csh, tcsh, 및 zsh보고서 것 없이 일치 오류 및 호출 할 것이다 rm(그리고 fish지원하지 않는 [...]와일드 카드)).

당신은 문자 그대로 전달하려는 경우 *에를 ls, 당신은 그 인용이 *같이 어떤 식 으로든 문자 ls \*또는 ls '*'ls "*". POSIX와 같은 쉘에서 사용하여 완전히 비활성화 할 수 있습니다 대체 (globbing) set -o noglob또는 set -f(후자에서 작동하지 않는 zsh에서하지 않는 한 sh/ ksh에뮬레이션).


¹ (*/)#항상 지원 되었지만 처음 ..../에는 zsh-2.0에서 와 같이 (그리고 잠재적으로 이전에), ****/2.1 **/에서 1992 년 초에 확정 된 형태 를 갖기 전에 2.1로 사용 되었습니다.


22
정말 좋은 답변입니다!
Andrea Corbellini 2012 년

7
또 다른 좋은 예는 find -name *입니다. 특히 더 복잡한 패턴을 사용하여 현재 디렉토리에 정확히 하나의 일치 항목이 있으면 사람들은 별표를로 전달하지 않는다는 사실을 종종 알지 못합니다 find.
njsg

나는 +1을 계속하고, 나는 unix.stackexchange.com 에서 Stephane Chazelas가 활성화되어있는 것을 정말로 기쁘게 생각합니다 ! 언제나처럼 큰 기여, 스테판!
Dimitre Radoulov

1
물고기에서는로 *.[ab]끝나는 모든 것을 삭제하려고 시도합니다 .[ab]. [물고기는 특별하지 않습니다.
Konrad Borowski

35

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

이 명령 ls *은 ' *쉘 패턴 확장시 ls를 실행합니다'를 의미합니다

*패턴은 쉘에 의해 처리하고, 그 시작을 제외하고, 현재의 디렉토리의 모든 항목 확장된다 .. 한 단계 깊숙이 갈 것입니다.

이중 또는 삼중 *패턴 의 해석은 사용 된 실제 쉘에 따라 다릅니다.

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


17
그 여분을 제외 * 뭔가를 추가 globstar을 설명하는 다른 대답을 참조하십시오. 또한 LS가없는 것이 분명해야한다 아무것도 별표와 함께 할을 전혀 이러한 별표 중 하나를 통과 적이 없어요. echo ls *당신이 쓸 때 무엇이 ​​실행될 것인지보기 위해 달려라 ls *.
njsg

12

명령이 무엇으로 확장되는지 확인하기 위해 먼저 입력하는 echo대신 전체 프로세스를 ls이해할 수 있습니다.

$ 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쉘로 사용한다고 가정합니다. 대부분의 사람들이 있고 다른 쉘은 다른 동작을합니다. ash또는 csh또는 ksh또는 또는를 사용하는 경우 zsh상황이 다르게 작동 할 수 있습니다. 그것은 다른 껍질을 가지고있는 요점입니다.

따라서 다른 작업을 계속 시도해 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 각 사용자에 대한 디렉토리를.


1
"이것은 당신이 bash당신의 쉘로 사용 하고 있다고 가정합니다 "← 그리고 globstar가 활성화되어 있지 않습니다. shopt -s globstar다시 시도해보십시오.
njsg

또 다른 방법 set -x은 "매번 실행되는"실제 "명령 인쇄를 시작하는 것 set +x입니다.
ShreevatsaR

10

globstar옵션이 활성화 된 bash 4.x를 포함한 일부 셸에서는 **일치하는 디렉토리를 내림차순으로 재귀 글로브를 수행합니다. 추가 별표는이 작업을 더 이상 수정하지 않습니다.


1
그래도 난 내 대답에 말했듯이,에 그 반대를 조심 ksh93하고 zsh, bash일반적으로 원치 않는 것입니다 재귀에 트래버스 심볼릭 링크를한다.
Stéphane Chazelas

그것은 bash 4.3에서 수정되었습니다
Stéphane Chazelas

1

"심층 다이빙"을하려면 ls -R (재귀) 옵션을 사용하거나 다음과 같이 find를 사용하십시오.

find . -ls

"find"는 디렉토리 트리의 맨 아래로 내려 가며 ( 'ls -R'처럼) 디렉토리 나열 (-type d), 파일 만 (-type f) 또는 다른 파일이있는 파일 표시와 같은 더 많은 옵션이 있습니다. 특성 (/ etc / passwd의 사용자, 특정 권한 및 그 이상) "find"는 스크립팅에서 다소 안전합니다 (쉘 사이에 일관성없는 글 로빙 규칙 및 대시가있는 파일의 특수 이스케이프 등).

쉘 와일드 카드 글 로빙은 점 파일에서 별표 '*'와 함께 작동하지 않습니다. 도트 파일 만 나열하려면 다음을 사용하십시오.

ls .??*


-1

추가 * 깊이 수준을 추가하지 않습니다. 하지만 시도하면

 ls */*/*

-현재 폴더의 폴더에 하위 폴더의 하위 폴더 목록이 표시됩니다.


잘못된. 쉘에 따라 여분 *의 깊이가 추가됩니다.
njsg

여분의 별에 깊이를 더할 쉘은 무엇입니까?
VB9-UANIC 2016 년

몇몇의. bashglobstar 옵션, korn 쉘 및 zsh와 함께 GNU 를 포함 합니다. 그리고 아마도 다른 것 같아요. unix.stackexchange.com/a/62665/14831
njsg

-1

내 주요 그립은 echo ** / *. ext가 일반적으로 ...

5 월 또는 5 월이 아님 : 현재 디렉토리에 .ext 파일 나열

5 월 또는 5 월 :. *. ext 파일 포함

일반적으로 glob 표현식을 '** /'로 설정하고 null 문자열 (하위 디렉토리 없음)을 초래할 수 있습니다. 이것이 프로그램 입력에서 glob 표현식을 변환하는 방법입니다. 물론 사용 예에서 이것을 설명하는 의견이 있음을 보증합니다.

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