답변:
$ 터치 ./-c $ 'a \ n12 \ tb'foo $ du -hs * 0 12 개 b 0 푸 총 0
당신이 볼 수 있듯이, -c파일에 옵션으로 찍은 du및보고되지 않습니다 (당신은 볼 수 total있기 때문에 라인을 du -c). 또한라는 a\n12\tb파일은 aand 라는 파일이 있다고 생각하게합니다 b.
$ du -hs -- *
0 a
12 b
0 -c
0 foo
그게 낫다. 적어도 이번에 -c는 옵션으로 사용되지 않습니다.
$ du -hs ./*
0 ./a
12 b
0 ./-c
0 ./foo
더 좋습니다. ./접두사 방지 -c에서는 옵션의 부재로 취해지고 ./전에 b출력이 전혀 없다 있음을 나타냅니다에서 b거기에 파일하지만, 개행 문자가있는 파일이있다 (그러나 아래 참조 1 가에 대한 자세한 여담을 위해).
./가능 하면 접두사 를 사용하는 것이 좋으며 , 그렇지 않은 경우 임의의 데이터에 대해서는 항상 다음을 사용해야합니다.
cmd -- "$var"
또는:
cmd -- $patterns
경우 cmd지원하지 않는 --옵션의 끝을 표시하려면 (이 선택에 의해 그리고에 대한처럼 문서화 된 경우를 제외하고 저자에 버그로보고해야한다 echo).
./*문제가 해결 --되지 않는 경우가 있습니다 . 예를 들어 :
awk -f file.awk -- *
a=b.txt현재 디렉토리에 호출 된 파일이 있으면 실패합니다 ( 파일 처리 a를 지시하는 b.txt대신 awk 변수 를 설정 ).
awk -f file.awk ./*
./a유효한 awk 변수 이름이 아니기 때문에 문제 가 없으므로 ./a=b.txt변수 할당으로 간주되지 않습니다.
cat -- * | wc -l
stdin에서 읽 -도록 지시 cat하는 것처럼 현재 디렉토리에 호출 된 파일이 있으면 실패합니다 ( -대부분의 텍스트 처리 유틸리티 및 cd/에 특수 함 pushd).
cat ./* | wc -l
./-특별하지 않기 때문에 OK cat입니다.
같은 것들:
grep -l -- foo *.txt | wc -l
포함 foo하는 파일 수를 계산하는 것은 파일 이름에 개행 문자가 포함되지 않는다고 가정하기 때문에 잘못되었습니다 ( wc -l개행 문자, grep각 파일 에 대한 출력 및 파일 이름 자체의 수). 대신 사용해야합니다 :
grep -l foo ./*.txt | grep -c /
/파일 이름 당 하나만있을 수 있으므로 문자 수를 계산하는 것이 더 안정적입니다.
재귀 grep의 경우 동등한 트릭은 다음을 사용하는 것입니다.
grep -rl foo .//. | grep -c //
./* 그래도 원하지 않는 부작용이있을 수 있습니다.
cat ./*
파일 당 두 문자를 더 추가하므로 인수의 최대 크기 + 환경의 한계에 빨리 도달 할 수 있습니다. 때로는 ./출력에보고하기를 원하지 않습니다 . 처럼:
grep foo ./*
출력 :
./a.txt: foobar
대신에:
a.txt: foobar
1 . 의견에 대한 토론에 따라 여기에서 확장해야한다고 생각합니다.
$ du -hs ./*
0 ./a
12 b
0 ./-c
0 ./foo
위 ./의 각 파일의 시작 을 표시한다는 것은 각 파일 이름이 시작되는 위치 (at ./)와 끝나는 위치 ( ./출력 의 다음 또는 끝 이전 줄 바꿈)를 명확하게 식별 할 수 있음을 의미 합니다.
그 의미는의 출력과 du ./*는 반대로 du -- *스크립트에서 쉽게 출력되지는 않지만 안정적으로 구문 분석 될 수 있다는 것입니다.
출력이 터미널로 갈 때 파일 이름이 당신을 속일 수있는 더 많은 방법이 있습니다.
\r커서를 줄의 시작 부분으로 \b이동하고 커서를 뒤로, \e[C앞으로 (대부분의 터미널에서) 뒤로 이동합니다 .대부분의 글꼴에서 슬래시와 동일하게 보이는 유니 코드 문자가 있습니다.
$ printf '\u002f \u2044 \u2215 \u2571 \u29F8\n'
/ ⁄ ∕ ╱ ⧸
(브라우저에서 어떻게 작동하는지 확인하십시오).
예를 들면 :
$ touch x 'x ' $'y\bx' $'x\n0\t.\u2215x' $'y\r0\t.\e[Cx'
$ ln x y
$ du -hs ./*
0 ./x
0 ./x
0 ./x
0 .∕x
0 ./x
0 ./x
의 많은 x있지만 y누락되었습니다.
GNUls 와 같은 일부 도구 ∕는 출력이 터미널로 갈 때 인쇄 할 수없는 문자를 물음표 (U + 2215는 인쇄 가능함)로 바꿉니다. GNU du는 그렇지 않습니다.
그들이 스스로를 드러 낼 수있는 방법이 있습니다 :
$ ls
x x x?0?.∕x y y?0?.?[Cx y?x
$ LC_ALL=C ls
x x?0?.???x x y y?x y?0?.?[Cx
방법을 참조하십시오 ∕으로 향했다 ???우리가 말한 후에 ls우리의 문자 집합이 ASCII했다.
$ du -hs ./* | LC_ALL=C sed -n l
0\t./x$
0\t./x $
0\t./x$
0\t.\342\210\225x$
0\t./y\r0\t.\033[Cx$
0\t./y\bx$
$줄의 끝을 표시하므로 "x"vs를 확인할 수 있습니다. "x "인쇄 할 수 없는 모든 문자와 비 ASCII 문자는 백 슬래시 시퀀스로 표시됩니다 (백 슬래시 자체는 두 개의 백 슬래시로 표시됨). 그것은 GNU 였고 sed, 모든 POSIX 호환 sed구현 에서 동일해야 하지만 일부 오래된 sed구현은 거의 도움이되지 않습니다.
$ du -hs ./* | cat -vte
0^I./x$
0^I./x $
0^I./x$
0^I.M-bM-^HM-^Ux$
(표준은 아니지만 cat -A일부 구현 에서도 매우 일반적입니다 ). 즉, 하나의 유용하고 다른 표현을 사용하지만, 모호 ( "^I"및 <TAB>표시 인스턴스에 대해 동일).
$ du -hs ./* | od -vtc
0000000 0 \t . / x \n 0 \t . / x \n 0 \t .
0000020 / x \n 0 \t . 342 210 225 x \n 0 \t . / y
0000040 \r 0 \t . 033 [ C x \n 0 \t . / y \b x
0000060 \n
0000061
그것은 표준적이고 모호하지 않으며 (구현마다 구현에 일관성이 있지만) 읽기 쉽지 않습니다.
당신은 y위에 나타나지 않았다는 것을 알 수 있습니다. 파일 이름 과 관련이 없지만 완전히 관련이없는 문제du -hs * 이지만 주목해야합니다. du디스크 사용을보고 하므로 이미 나열된 파일에 대한 다른 링크를보고하지 않습니다 ( du하드 링크가 나열되어있을 때 모든 구현이 그렇게 동작 하지는 않습니다) 명령 행에서).
[a-z0-9.+-].
/tmp) 또는 고가의 자동차가 많은 지역 ( ) 에 주차하면 $HOMEQ & A 사이트로 이동하는 것이 더 나쁘며 어떤 조건에서든 차를 잠그지 않는 것이 좋습니다 (잠긴 차고, 스크립트) 당신은 어떤 네트워크 또는 이동식 저장 장치에 연결되지 않은 컴퓨터에서만 혼자서 작성했습니다 ...)
"b "또는 같은 "a\bb")는 터미널에서 사용자를 속일 수 있지만의 출력을 구문 분석하는 스크립트는 아닙니다 du ./*. 아마 그것에 대한 메모를 추가해야합니다. 내일 할거야. 이전에 나는 일반적인 의미로 특권 을 의미 root했지만 (물론 모든 것에 더 적용됨 root). 개행은 허용되며 무시하는 것은 버그입니다. 버그는 악용되는 습관이 있습니다. 사례별로 위험을 측정해야합니다. 좋은 코딩 방법은 많은 경우에 문제를 피할 수 있습니다. 확실히 SE에서는 인지도를 높여야합니다.
어떤 파일을 나열할지에 관해서는 a *와 차이가 없습니다 ./*. 유일한 차이점은 두 번째 형식이며 각 파일 ./앞에는 점 슬래시가 있으며 이는 일반적으로 현재 디렉토리를 의미합니다.
기억 .디렉토리가 현재 디렉토리에 대한 속기 표기법입니다.
$ ls -la | head -4
total 28864
drwx------. 104 saml saml 12288 Jan 23 20:04 .
drwxr-xr-x. 4 root root 4096 Jul 8 2013 ..
-rw-rw-r--. 1 saml saml 972 Oct 6 20:26 abcdefg
echo쉘이 무엇을 확장 시키는 지보기 위해이 두리스트가 본질적으로 같은 것임을 확신 할 수 있습니다 .
$ echo *
$ echo ./*
이 두 명령은 현재 디렉토리의 모든 파일을 나열합니다.
다음과 같이 가짜 데이터를 만들 수 있습니다.
$ touch file{1..5}
$ ll
total 0
-rw-rw-r--. 1 saml saml 0 Jan 24 07:14 file1
-rw-rw-r--. 1 saml saml 0 Jan 24 07:14 file2
-rw-rw-r--. 1 saml saml 0 Jan 24 07:14 file3
-rw-rw-r--. 1 saml saml 0 Jan 24 07:14 file4
-rw-rw-r--. 1 saml saml 0 Jan 24 07:14 file5
위의 echo명령 을 사용 하면 다음과 같은 출력이 나타납니다.
$ echo *
file1 file2 file3 file4 file5
$ echo ./*
./file1 ./file2 ./file3 ./file4 ./file5
이 차이는 불필요하게 보일 수 있지만 명령 줄을 통해 파일 이름을 파일 이름으로 전달하는 다양한 유닉스 명령 줄 도구를 보장하려는 상황이 있습니다!
로 스테판의 대답은 지적 @ 때문에 유닉스의 파일 및 디렉토리의 이름을 지정할 때 문자가 법적 무엇의 특성으로 위험한 파일 이름은 명령 줄에서 다양한 유닉스 명령에 전달 할 때 예상치 못한 부작용이있는 구성 할 수있다.
따라서 ./다양한 Unix 명령에 인수로 전달 될 때 확장 된 파일 이름이 파일 이름으로 간주되도록 보장하는 데 종종 사용 됩니다.