현재 디렉토리를 이동할 때 "mv: `.'를 이동할 수 없습니다.'라는 메시지가 나타납니다. `../dir/.'로: 장치 또는 리소스가 사용 중입니다."

현재 디렉토리를 이동할 때 "mv: `.'를 이동할 수 없습니다.'라는 메시지가 나타납니다. `../dir/.'로: 장치 또는 리소스가 사용 중입니다."
$ 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_DOTLAST_DOTDOT

FreeBSD는 이러한 각 경우에 EINVAL 오류를 반환합니다.


우리는 왜 이러한 제한이 있는지 추측할 수 있을 뿐입니다.

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] 경로 인수에 점인 마지막 구성 요소가 포함되어 있습니다.

관련 정보