
$ mv . ../general/
mv: cannot move `.' to `../general/.': Device or resource busy
현재 디렉터리가 사용 중인 장치나 리소스이므로 다른 곳으로 이동할 수 없다는 뜻인가요? 왜 그럴까요?
답변1
현재 있는 디렉터리는 이동할 수 없습니다. 현재 프로세스가 계속 바쁘게 지내고 있는 프로세스입니다.
대신 한 수준 위로 이동하여 이전 현재 디렉터리의 이름을 지정하여 대상으로 이동하세요.
답변2
점을 이동할 수 없습니다 .
. 점이 현재 디렉터리 이름과 동일하지 않습니다. 디렉토리에 대한 포인터로 생각할 수 있지만 .
디렉토리 자체는 아닙니다.
$ pwd && echo $PWD && realpath .
/home/jimmij/tmp
/home/jimmij/tmp
/home/jimmij/tmp
$ mkdir tmp1 tmp2
$ mv tmp1/. tmp2/
mv: cannot move ‘tmp1/.’ to ‘tmp2/.’: Device or resource busy
작동하지 않지만
cd tmp1
mv ../tmp1 ../tmp2
잘 작동합니다. 그래서 사실 당신은~할 수 있다현재 디렉터리를 이동합니다. 단, 이 작업 후에 일부 명령이 혼동될 수 있습니다.
$ pwd && echo $PWD && realpath .
/home/jimmij/tmp/tmp1
/home/jimmij/tmp/tmp1
/home/jimmij/tmp/tmp2/tmp1
$ cd .
$ pwd && echo $PWD && realpath .
/home/jimmij/tmp/tmp2/tmp1
/home/jimmij/tmp/tmp2/tmp1
/home/jimmij/tmp/tmp2/tmp1
..
, 즉 상위 디렉토리 와 비슷한 이야기입니다 .
즉, 각 디렉토리에는 최소 두 개의 요소( .
및 ) 가 포함되어야 합니다 ..
. 이동하거나 삭제할 수 없습니다.
답변3
메시지를 받는 이유:
mv: 이동할 수 없습니다
.' to
. ../general/.': 장치 또는 리소스가 사용 중입니다.
.
는 , 및 가 ..
와 함께 작동하는 방식 때문입니다 mv
. Unix에서 무언가를 이동할 때 mv
명령은 이동하려는 항목의 inode를 참조하는 모든 항목의 연결을 해제하려고 시도합니다. 이 경우에는 참조하는 디렉토리의 inode가 됩니다 .
.
"기호/링크" 는 inode에 연결 .
되며 ..
어떤 의미에서는 특별합니다. U&L Q&A에서 다음과 같은 역사를 읽을 수 있습니다.새 디렉토리에 무엇인가 추가되기 전에 하드 링크 수가 2인 이유는 무엇입니까?새로 생성된 디렉토리를 본 적이 있다면 항상 연결된 개수 2로 시작한다는 것을 알 수 있습니다. 그 이유는 및 의 존재 때문 .
입니다 ..
.
$ mkdir adir
$ ls -l | grep adir
drwxrwxr-x. 2 saml saml 4096 Oct 5 08:02 adir
$ ls -la adir/
total 8
drwxrwxr-x. 2 saml saml 4096 Oct 5 08:02 .
drwxrwxr-x. 3 saml saml 4096 Oct 5 08:02 ..
메모:ls
확실하지 않은 경우 출력 에 대한 참조는 다음 U&L Q&A에 있습니다.ls -al 출력의 필드는 무엇을 의미합니까?
따라서 실제 디렉터리의 이름이 아니라 해당 디렉터리에 연결되는 "기호/링크"입니다. 따라서 그들은 할 수 있기 전에 연결을 해제해야 했습니다 mv
.
명령이 를 사용하고 있기 때문에 명령 .
으로 연결을 해제할 수 없습니다 mv
. 따라서 메시지는 "장치 또는 리소스가 사용 중입니다"입니다.
참고자료
답변4
Linux는 구성요소 .
또는 로 끝나는 경로의 이름을 바꾸는 것을 금지하며 ..
EBUSY 오류를 반환합니다. 다음도 실패합니다.
$ mkdir a a/aa
$ mv a/aa/.. b
mv: cannot move ‘a/aa/..’ to ‘b/..’: Device or resource busy
이에 대한 코드는 에 있습니다 namei.c::renameat
. 다양한 함수에 전달될 때 경로 이름의 마지막 구성 요소는 또는 LAST_NORM
이 아닌 유형이어야 합니다 .LAST_DOT
LAST_DOTDOT
FreeBSD는 이러한 각 경우에 EINVAL 오류를 반환합니다.
우리는 왜 이러한 제한이 있는지 추측할 수 있을 뿐입니다.
- 그만큼이름 바꾸기를 위한 POSIX 표준다음과 같이 말합니다
rename() 함수는 다음과 같은 경우에 실패합니다.
...
[EBUSY] old 또는 new로 명명된 디렉토리가 현재 시스템이나 다른 프로세스에서 사용 중이며 구현에서는 이를 오류로 간주합니다.
.
현재 프로세스에서 사용 중이라고 생각할 수 있습니다 . 그러나 Linux에서는 다음을 허용하므로 단순히 일부 프로세스에서 사용 중인 디렉토리만으로는 rename
실패할 수 없습니다.
$ mkdir /tmp/t
$ cd /tmp/t
$ mv /tmp/t /tmp/t1
$ /bin/pwd
/tmp/t1
.
and 의 이름 변경을 금지하는 이유는 ..
아마도 "사용자 혼란을 줄이기 위한 것"일 것입니다.
.
일반적으로 상위 디렉터리 항목에 대한 하드 링크이며 프로세스가 항상.
현재 작업 디렉터리에 액세스하기 위해 열 수 있다는 점에서 다소 특별합니다. 이름을 바꿀 수 있으면 비생산적입니다...
일반적으로 디렉토리의 상위 디렉토리에 대한 하드 링크이며, 프로세스를 열면..
상위 디렉토리(또는 마운트 지점인 경우 디렉토리 자체)를 얻게 된다는 점에서 다소 특별합니다. 이름을 바꿀 수 있으면 비생산적입니다.
Linux는 또한 마지막 구성 요소가 (ENOTEMPTY) 또는 (EINVAL) rmdir
인 경로를 금지합니다. FreeBSD는 이들 각각에 대해 EINVAL 오류를 반환합니다. 그만큼..
.
rmdir에 대한 POSIX 표준이:
rmdir() 함수는 다음과 같은 경우 실패합니다.
...
[EINVAL] 경로 인수에 점인 마지막 구성 요소가 포함되어 있습니다.