:>filename.txt는 무슨 일을 하나요?

:>filename.txt는 무슨 일을 하나요?
:>filename.txt

예를 들어:

root@box$ dd if=/dev/zero of=file.txt count=1024 bs=1024
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.00536175 s, 196 MB/s
root@box$ ll
total 1024
-rw-r--r-- 1 root root 1048576 Nov 15 14:40 file.txt
root@box$ :>file.txt
root@box$ ll
total 0
-rw-r--r-- 1 root root 0 Nov 15 14:40 file.txt

이것은 다른가요 rm? 파일을 비우거나 삭제하는 다른 유사한 방법보다 더 빠르게 실행됩니까, 아니면 느리게 실행됩니까?

답변1

rm아시다시피 이는 단순히 파일 내용을 비우는 것입니다(파일을 자릅니다). 이는 실제로 rm파일을 완전히 삭제하는 것과는 다릅니다 . 게다가 :>file.txt실제로는만들다아직 존재하지 않는 경우 이 파일입니다.

:성공적으로 종료되고 출력이 생성되지 않는 "아무 것도 하지 않는 명령"이므로 파일을 비우는 간단한 방법일 뿐입니다. 대부분의 쉘에서는 >file.txt간단히 이렇게 하면 동일한 결과를 얻을 수 있습니다. 또한 외부 명령과 같은 다른 방법보다 약간 더 빠를 수도 echo >file.txt있습니다 echo.

echo >file.txt또한 내부에 빈 줄이 배치되어 파일에 내용이 없습니다.file.txt:>file.txt

답변2

네, 다릅니다 rm.

rm파일이 삭제됩니다.

:>filename.txt파일이 여전히 존재하지만 크기가 0바이트가 되도록 파일을 비웁니다.

답변3

쉘 호출은 >filename.txt일부 출력을 "filename.txt" 파일로 리디렉션하여 완전히 대체합니다. 따라서 쉘은 지정된 파일에 출력을 쓰기 전에 지정된 파일의 모든 내용을 지워야 합니다.

리디렉션되는 출력은 실행된 명령의 출력입니다. 좋다:

$ echo Hello >filename.txt

filename.txt라는 파일에 문자열만 정확하게 포함됩니다 Hello.

구현하다:

$ echo "New Value" >filename.txt
$ cat filename.txt
New Value

파일 내의 모든 내용이 지워진 다음 New Value파일에 기록됩니다.

명령에 출력이 없으면(명령에서와 같이) true파일은 비어 있는(잘린 상태) 상태로 유지됩니다.

$ true >filename.txt
$ cat filename.txt

쉘 내장 명령이기도 한 명령은 :(단지 이중 점(콜론))이며 출력이 없습니다. 내장 명령이므로 true출력이 없는 외부 명령보다 빠릅니다. 따라서 다음 중 하나를 수행하세요.

$ :  >  filename.txt
$ :  >filename.txt
$ :>filename.txt

지정된 파일에서 모든 내용이 삭제되며 filename.txt, 존재하지 않는 경우 빈 파일로 생성됩니다.

rm이랑 다른건가요?

이는 rm과 다릅니다. rm은 ls파일에 0바이트를 포함시키는 대신 파일을 사라지게 만들기 때문입니다.

파일을 비우거나 삭제하는 다른 유사한 방법보다 더 빠르게 실행됩니까, 아니면 느리게 실행됩니까?

다시 말하지만, 파일은 삭제되지 않고(주어진 목록에서 사라짐 ls) 빈 파일(0바이트 포함)로 변환됩니다.

파일을 비우기 위해 외부 명령을 호출하는 것보다 빠릅니다. 실행 파일과 명령을 로드하려면 하위 쉘을 생성해야 하므로 exec외부 명령이 내장 명령보다 느려집니다 :.

유사한 솔루션은 다음과 같습니다(일부는 $?1로 설정됨).

[ ]         > filename.txt
builtin     > filename.txt
command     > filename.txt
printf ''   > filename.txt

답변4

답: 성능: 이는 쉘에서 가능한 한 효율적입니다. 단순히 커널에 기존 파일을 자르도록 요청하는 것이 파일 링크를 해제하고 동일한 이름으로 새 inode를 다시 생성하는 것보다 더 효율적입니다. 너가 아니라면생각하다파일이 삭제되었습니다. 이 경우에는 rm여전히 unlink남아 있습니다.

:내장 쉘이므로 포크/실행이 필요하지 않습니다. true일반적인 현대 껍질의 경우에도 마찬가지입니다.

>foo또는 시스템 호출을 통해 true > foo쉘이 파일을 자르도록 합니다 .
open(path, O_WRONLY|O_TRUNC|O_CREAT, 0666)

strace sh또는 출력 을 판단하여 Linux에서 DASH를 사용하여 연습해 보십시오 .
openat(AT_FDCWD, "foo", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 이는 동일합니다.

그럼 다시 그 FD로 가야 해요 close(). 실제로 DASH를 사용할 때는 특별한 경우가 없으며 :>다음 단계를 건너뜁니다.

openat(AT_FDCWD, "foo", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(1, F_GETFD)                       = 0
fcntl(1, F_DUPFD, 10)                   = 10          # save original stdout
fcntl(1, F_GETFD)                       = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
dup2(3, 1)                              = 1           # redirect stdout to foo
close(3)                                = 0           # then close 3
dup2(10, 1)                             = 1           # then restore original stdout
fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
close(10)                               = 0

DASH에서 사용하면 > foo동일한 시스템 호출 시퀀스가 ​​발생하여 실제로 fd1을 리디렉션한 다음 복원합니다. 나는 수표 bash나 다른 껍질이 없습니다 .

그러나 실행할 새 프로세스를 생성하고 truncate -s 0 foo(희망적으로) 단일 프로세스를 만드는 것보다 여전히 훨씬 저렴합니다.truncate("foo", 0)시스템 호출open이는 + 보다 더 효율적일 수 있습니다 close.

C(또는 시스템 호출 바인딩이 있는 모든 언어)에서는 열고 싶지 않은 파일은 직접 시스템 호출을 통해 가장 효율적으로 잘립니다 truncate.

Dash에서는 3>foo다음과 같은 시스템 호출 순서가 발생합니다.

openat(AT_FDCWD, "foo", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(3)                                = 0

새 fd를 열면 이미 fd 3이 되어 중복이 방지됩니다. 이는 대시에서 가장 효율적인 방법으로, 아마도 >foo. 이것이 중요하다면 쉘 스크립팅 언어는 귀하의 작업에 적합하지 않습니다! 하지만 당신은 물었습니다.


Spectre+Meltdown 완화를 활성화하면 -ENOSYS최신 Intel x86-64에서 잘못된 시스템 호출에도 최소 수천 클럭 사이클(예: 마이크로초)이 소요됩니다. 단 하나의 명령으로 syscall수백 번의 사용자->커널->사용자 왕복을 달성할 수 있습니다 . 물론 경로 조회 등은 파일 시스템 코드와 마찬가지로 많은 시간이 걸립니다. 커널 모드로 들어갔다가 돌아오면 일반적으로 일부 캐시가 제거되어 반환 시 사용자 공간 실행 속도가 느려집니다.

메타데이터를 디스크에 다시 기록한 후의 실제 I/O 비용은 파일 시스템에 따라 다릅니다. XFS 또는 최신 ext4와 같은 FS는 전체 파일에서 1개 또는 몇 개의 큰 범위만 사용하여 O(1) 시간에 많은 공간을 쉽게 확보할 수 있습니다. 또는 O(n), 여기서 는 n바이트 크기가 아닌 범위(조각) 수입니다.

FS에 따르면, 익스텐트 정보가 간접 블록이 아닌 아이노드에 직접 저장된다면, 여유 목록에 추가할 것이 하나 줄어든다.

I/O 비용은 파일 링크 해제와 비슷하지만 inode를 해제하거나 디렉터리 항목을 수정할 필요는 없습니다. 잘라낼 때 inode에서 mtime과 ctime을 업데이트해야 하지만 크기가 변경되면 어쨌든 이에 작성해야 합니다.

관련 정보