ls *, ls ** 및 ls ***의 결과 ls *명령은 무엇을합니까? 나는 그것을 사용했고 단지

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



답변

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로 사용 되었습니다.


답변

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

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

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

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

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


답변

명령이 무엇으로 확장되는지 확인하기 위해 먼저 입력하는 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 각 사용자에 대한 디렉토리를.


답변

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


답변

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

find . -ls

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

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

ls .??*


답변

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

 ls */*/*

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


답변

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

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

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

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