현재 디렉터리를 이동할 때 "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: ../general/을 이동할 수 없습니다 .' to. ': 장치 또는 리소스가 사용 중입니다.

무엇 때문에 ., 그리고 ..직장 밖에서 mv. Unix에서 무언가를 이동할 때 이 mv명령은 이동하려는 항목의 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에서는 .구성요소 또는 로 끝나는 경로의 이름을 바꾸는 것이 금지되어 있으며 .., 다음 오류가 반환되면 실패합니다.

$ mkdir a a/aa
$ mv a/aa/.. b
mv: cannot move ‘a/aa/..’ to ‘b/..’: Device or resource busy

이에 대한 코드는 에 있습니다 . 다양한 함수에 전달될 때 경로 이름의 마지막 구성 요소 는 또는 이 아닌 namei.c::renameat유형이어야 합니다 .LAST_NORMLAST_DOTLAST_DOTDOT

FreeBSD는 모든 경우에 EINVAL 오류를 반환합니다.


우리는 왜 이런 제한이 존재하는지 추측할 수 있을 뿐입니다.

rename() 함수는 다음과 같은 경우에 실패합니다.
...
[EBUSY] 기존 또는 새 디렉토리로 명명된 디렉토리가 현재 시스템이나 다른 프로세스에서 사용 중이며 구현에서는 이를 오류로 간주합니다.

.현재 프로세스에서 사용되고 있다고 생각할 수 있습니다 . 그러나 Linux에서는 다음 작업을 허용하므로 단순히 프로세스가 디렉터리에서 사용하는 것만으로는 rename오류가 발생하기에 충분하지 않습니다.

$ mkdir /tmp/t
$ cd /tmp/t
$ mv /tmp/t /tmp/t1
$ /bin/pwd
/tmp/t1

.이름 바꾸기를 비활성화하는 이유는 .."사용자 혼란을 줄이기 위한 것"일 수 있습니다.

  • .일반적으로 상위 디렉터리의 디렉터리 항목에 대한 하드 링크이며 프로세스가 .현재 작업 디렉터리에 액세스하기 위해 항상 열려 있다는 점에서 다소 특별합니다. 이름을 바꿀 수 있으면 비생산적입니다.
  • ..일반적으로 디렉토리의 상위 디렉토리에 대한 하드 링크이며, 열린 프로세스가 ..상위 디렉토리(또는 마운트 지점인 경우 디렉토리 자체)를 얻는다는 점에서 다소 특별합니다. 이름을 바꿀 수 있으면 비생산적입니다.

Linux는 또한 마지막 구성 요소가 (ENOTEMPTY) 또는 (EINVAL) 인 rmdir경로를 비활성화합니다. FreeBSD는 이들 각각에 대해 EINVAL 오류를 반환합니다. 이것...rmdir에 대한 POSIX 표준이것이 있다:

rmdir() 함수는 다음과 같은 경우에 실패합니다.
...
[EINVAL] 경로 인수에 점인 마지막 구성 요소가 포함되어 있습니다.

관련 정보