mv / dev / null에 파일을 보내면 dev / null이 중단됩니다.


25

내가하면 : touch file; mv file /dev/null루트로 /dev/null사라집니다. ls -lad /dev/null그러한 파일이나 디렉토리가 없습니다. 이것은 /dev/nullSSH와 같은 응용 프로그램을 중단하고을 수행하여 해결할 수 있습니다 mknod /dev/null c 1 3; chmod 666 /dev/null. 일반 파일을이 특수 파일로 옮기면 왜 사라 /dev/null집니까?

명확히하기 위해 이것은 테스트 목적이며 mv명령 이 어떻게 작동 하는지 이해합니다 . 내가 궁금한 점은 ls -la /dev/null일반 파일로 바꾸기 전에 예상 출력을 보여 주지만 나중에 /dev/null원래 mv명령을 통해 파일이 생성 되고 파일 명령이 ASCII 텍스트를 표시 한다고해도 존재하지 않는 것을 보여줍니다 . 비 특수 파일이 문자 / 특수 파일을 대체 할 때 ls와 함께 명령 동작 의 조합이어야한다고 생각 devfs합니다. 이것은 Mac OS X에 있으며 동작은 다른 OS에 따라 다를 수 있습니다.


44
엉망하지 마십시오 /dev/null.
devnull

7
@devnull이 말합니다
Braiam

3
파일을 삭제하는 올바른 방법은 rm명령입니다.
casey

1
그것은 문제의 근원 인 것처럼 보입니다 .OSX devfs는 일반 파일에 대해 재미 있습니다. mv그래도 이상한 오류가 발생하지 않았습니다 . 이 방법은 touch testfile; mv testfile /dev어떻습니까?
Graeme

3
@Gregg mv는 동일한 파일 시스템에서만 원자가 될 수 있습니다.
Graeme

답변:


16

mv의 소스 코드를 보면 http://www.opensource.apple.com/source/file_cmds/file_cmds-220.7/mv/mv.c입니다 .

/*
 * If rename fails because we're trying to cross devices, and
 * it's a regular file, do the copy internally; otherwise, use
 * cp and rm.
 */
if (lstat(from, &sb)) {
    warn("%s", from);
    return (1);
}
return (S_ISREG(sb.st_mode) ?
    fastcopy(from, to, &sb) : copy(from, to));

...

int
fastcopy(char *from, char *to, struct stat *sbp)
{
...
while ((to_fd =
    open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)) < 0) {
        if (errno == EEXIST && unlink(to) == 0)
            continue;
        warn("%s", to);
        (void)close(from_fd);
        return (1);
}

while 루프를 통한 첫 번째 패스에서 open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)EEXIST와 함께 실패합니다. 그런 다음 /dev/null연결이 해제되고 루프가 반복됩니다. 그러나 의견에서 지적했듯이에서 일반 파일을 만들 수 없으므로 /dev다음 번 루프를 통과 open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)해도 여전히 실패합니다.

Apple에 버그 보고서를 제출했습니다. mv소스 코드는 FreeBSD의 버전에서 대부분 변경되지 않습니다,하지만 OSX의 devfs가 있기 때문에 일반 파일과 그 비 POSIX 동작을 가지고, 애플은 자신의 문제를 해결해야한다 mv.


1
나는 소스 코드를 제공하고 이것을 버그로 인정하여 지금이 최선의 해답을주고 있습니다.
Gregg Leventhal

12

기존 파일 위치로 파일을 이동하면 기존 파일이 대체됩니다. 이 경우 /dev/null일반 파일과 마찬가지로 장치 파일이 교체됩니다. 이를 피하려면 -i(대화식, 덮어 쓰기 전에 경고) 또는 -n(복제 장치 없음) 옵션을 사용하십시오 mv.

/dev/null비트 버킷으로 만 특수 기능을 수행하면 장치가 그대로 열립니다. 예를 들어, >셸 연산자를 사용하면 파일이 열리고 잘립니다 (바꾸지 않은 제거되지 않음). casey가 언급했듯이 파일을 제거하는 올바른 방법은 또는를 사용하는 rm것입니다 unlink.


terdon에 대한 내 의견을 참조하십시오.
Gregg Leventhal

-d는 불필요합니다. 나쁜 습관 일 뿐이지 만 파일이 여전히 ls 출력에 표시되어야하며 존재하지 않는 것으로 표시되어서는 안됩니다.
Gregg Leventhal

@Graeme-3K에 오신 것을 환영합니다.
slm

10

음, 특수 파일을 일반 파일로 덮어 쓰기 때문에? 무슨 일이 있었나요? dev/null디렉토리가 아니라 null장치를 가리키는 파일 입니다. 당신이 mv뭔가를 할 때, 당신은 원본을 삭제하고 당신이 움직 인 것으로 대체합니다 :

$ file /dev/null 
/dev/null: character special 
$ sudo mv file /dev/null 
$ file /dev/null 
/dev/null: ASCII text

2
그러나 ls -lad / dev / null을 실행할 때 / dev / null이 누락 된 것으로 표시됩니다. 이것은 내가 알고 싶었던 devfs에 특정한 것이어야합니다.
Gregg Leventhal

mv 파일 / dev / null 인 경우 / dev / null에는 어떤 파일이 포함되어 있지만 여전히 존재해야합니다. 왜 이것이 ls에서 / dev / null을 찾을 수 없었는지 알고 싶습니다.
Gregg Leventhal

물론 Mac 에서이 작업을 수행하고 있으므로 약간 다를 수 있지만 파일이 누락 된 것으로 표시하지는 않았지만 소스 파일이 변경된 것으로 표시되기를 기대했습니다.
Gregg Leventhal

@GreggLeventhal 예, OSX 또는 BSD 일이어야합니다 (Q를 편집하고 OS를 지정하십시오). 내 리눅스에서는 여전히 볼 수 있습니다 /dev/null. 이것은 내가 이동 한 파일이됩니다.
terdon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.