mv vs cp: 결과 파일의 차이점은 무엇입니까?

mv vs cp: 결과 파일의 차이점은 무엇입니까?

일부 애플리케이션의 구성 파일이 제대로 포함되지 않는 버그가 있어서 파일에서 문제가 있는 줄을 분리하기 위해 이전 내용을 한 번에 몇 줄씩 새 파일에 복사했습니다.

결국, 나는 파일의 정확한 복사본을 만들었지만 이전 파일은 여전히 ​​작동하지 않는 반면 새 파일은 완벽하게 작동했습니다.

더 중요한 점은 mv명령을 사용하여 파일을 저장한 위치에서 원하는 위치로 파일을 이동하면 오류가 발생한다는 것입니다. cp파일을 원하는 위치에 복사 하면 오류가 없습니다.

분명히 , 또는 와 diff같은 항목은 하나가 다른 파일의 복사본이기 때문에 두 파일 간의 차이점을 드러내지 않습니다.filels -lcp파일의 정확한 복사본을 만드는 한.

파일에 대한 너무 많은 정보를 공유할 수는 없습니다. 왜냐하면 이것은 업무적인 일이기 때문입니다. 결론은 명령 cp fileA fileBmv fileA fileB"다른" 파일을 생성한다는 것입니다. 내 추측으로는 fileB의 매우 낮은 수준의 속성이 도중에 남아 있다는 것입니다 cp(심지어 cp -p동일한 동작을 생성함).

결과 파일의 정확한 내용과 관련하여 mv는 cp와 다르게 무엇을 수행합니까?

편집 : 다음과 같이 ls -l:

-rw-r--r--. 1 root root 3389 Aug  8 22:53 fileA
-rw-r--r--. 1 root root 3389 Aug  8 23:03 fileB

편집: 응용 프로그램은 mysql이고 파일은 .cnf 파일이며 이 구성 파일에서 특히 관심 있는 항목은 마스터-슬레이브 데이터베이스 복제에 사용되는 바이너리 로그의 이름입니다. "오류"는 "바이너리 로깅을 사용하고 있지 않습니다"입니다. 왜냐하면 해당 항목이 mysql에 의해 "읽혀"지지 않았기 때문에 바이너리 로그가 없기 때문입니다.

내 초기 생각은 구성 파일에 구문 오류가 있어 전체 내용을 읽을 수 없다는 것이었습니다. 이로 인해 텍스트 블록을 복사하여 수동으로 다시 생성하게 되었습니다.

편집: 어딘가에 가는 중... 마지막으로 파일에 대해 뭔가 다른 점이 있습니다.

ls -lZ

-rw-r--r--. root root unconfined_u:object_r:user_home_t:s0 server.cnf.bad
-rw-r--r--. root root unconfined_u:object_r:mysqld_etc_t:s0 server.cnf.good

답변1

핵심요약: DR: 시스템에서SELinux사용 중인 경우 시스템에서 사용하는 파일(예: 데몬)은 cp -aZmv -Z대신 cp -a및 를 사용하여 복사하거나 이동해야 합니다 mv. 이것이 완료되지 않은 경우 대상에서 restorecon -v -r또는 를 사용하여 시스템에 기본 SELinux 컨텍스트를 복원하도록 요청해야 합니다. restorecon -v -F -r항상 잘 활용하고 있는 것 같아요restorecon주요 구성 파일에 대해 작업한 스크립트의 끝 부분에 있습니다.

RHEL 및 그 파생물 대부분기본적으로 SELinux 사용.

따라서 문제를 해결하려면 시스템이 RHEL 기반이고 패키지를 사용하는 경우 mariadb-server파일이 다음 위치에 있을 때 마지막 단계에서 수행하십시오.정확한 장소:

# restorecon -v -F /etc/my.cnf.d/server.cnf
Relabeled /etc/my.cnf.d/server.cnf from unconfined_u:object_r:user_home_t:s0 to system_u:object_r:mysqld_etc_t:s0

(그것이 없으면 구성된 으로 -F변경되지 않을 것 입니다. 일반적인 시스템에서는 중요하지 않습니다. 차이점과 그것이 중요하지 않은 이유에 대한 나의 지식은 여기까지 가지 않습니다).unconfined_usystem_u

파일에 올바른 컨텍스트를 추가하는 것은 더 많은 작업이 될 것입니다.다른장소.chcon이를 수행할 수 있습니다(등으로 명시하거나 -u -t, 더 간단하게 로 다른 파일의 컨텍스트를 복사하여 --reference).

# ls -lZ /home/test/server.cnf.bad
-rw-r--r--. 1 root root unconfined_u:object_r:user_home_t:s0 744 Apr 30  2017 /home/test/server.cnf.bad
# chcon -v -u system_u -t mysqld_etc_t /home/test/server.cnf.bad 
changing security context of '/home/test/server.cnf.bad'
# ls -lZ /home/test/server.cnf.bad
-rw-r--r--. 1 root root system_u:object_r:mysqld_etc_t:s0 744 Apr 30  2017 /home/test/server.cnf.bad

SELinux 문제가 의심되는 경우 프로세스 또는 파일과 관련된 /var/log/audit/audit.log단어가 포함된 항목을 확인하세요. denied언제든지 일시적으로 SELinux에 작업을 허용하도록 요청한 다음 각각 복원하고 동작을 비교할 수 setenforce Permissive있습니다 setenforce Enforcing. 특히 생산을 위해 방치하지 마십시오 Permissive.

이어지는 다양한 설명...

예와 구성 파일 작업 시 수행해야 할 작업

cp다양한 옵션이 있고 mvSELinux 지원 시스템에서 동작의 예 :

$ id
uid=1034(test) gid=1034(test) groups=1034(test)
$ pwd
/home/test
test@glasswalker:~$ ls -lZ foo
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:25 foo
$ cp foo /tmp/foo1
$ cp --preserve=context foo /tmp/foo2
$ cp -a foo /tmp/foo3
$ cp -aZ foo /tmp/foo4
$ mv foo /tmp/foo5
$ ls -lZ /tmp/foo?
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:25 /tmp/foo1
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo2
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo3
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:25 /tmp/foo4
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo5
$ touch bar
$ ls -lZ bar
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:49 bar
$ mv -Z bar /tmp
$ ls -lZ /tmp/bar
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:49 /tmp/bar

따라서 보안 컨텍스트가 중요하고 다른 속성을 유지하는 경우 cp -aZor를 사용하면 잘 작동합니다. mv -Z시스템 파일을 이동하는 스크립트는 항상 -Zany cp또는 mv명령에 옵션을 사용해야 하며, restorecon예상치 못한 문제를 방지하려면 마지막 단계에서만 사용해야 합니다.

왜 그런 차이가 있는 걸까요?

명령 mv은 일관된 동작을 유지합니다. 동일한 파일 시스템에서 발생한 경우 보안 컨텍스트를 포함하여 파일에 첨부된 모든 항목은 단지 "이름 바꾸기"이므로 변경되지 않습니다. 따라서 실제로 복사 후 삭제되는 두 파일 시스템에서 일관성을 위해 보안 컨텍스트를 포함하여 파일에 첨부되고 알고 있는 모든 것을 변경되지 않은 채로 복사합니다.

cp기본적으로 명령 은창조하다새 파일이므로 이 파일 --preserve=context-a. 옵션을 사용하여 --preserve=context제외할 수 있으므로 전체 수목을 복사할 때 가장 좋은 방법은 SELinux가 중요한 경우 대신 사용하는 것입니다.-a-Z-aZ-a

기본적으로 파일을 생성할 때(일반적인 경우) 이 새 파일은 디렉터리 SELinux 컨텍스트를 상속하므로 모든 것이 잘 작동합니다(주제에서 벗어남: 드문 경우지만 파일 컨텍스트는 단지 이름을 규칙으로 정하면 커널은 신경 쓰지 않을 것입니다. 데몬과 같은 프로그램은restorecond처리해야 합니다.)

SELinux 란 무엇입니까?

SELinux는 필수 액세스 제어 메커니즘(일명)는 다른 모든 메커니즘(일명 Unix 권한)과 함께 사용됩니다.DAC, 액세스 제어 목록이라고도 함ACL등.). 프로세스가 프로세스 보안 컨텍스트에서 실행될 때 이를 확인하는 "규칙 매트릭스"가 있습니다.프로세스컨텍스트는 요청된 작업(열기, 읽기, 쓰기, mmap 등)을 수행할 수 있습니다.파일상황에 따라 작업하려고 합니다.

OP 사례의 예: mysqld의 프로세스 컨텍스트가 몇 가지 파일 컨텍스트 유형에만 액세스하도록 허용되지만 mysqld_etc_t그렇지 않은 경우 잘못된 유형의 구성 파일을 읽을 수 없기 때문에 user_home_t시작이 실패합니다 .mysqlduser_home_t

일반적인 시스템에서는 대화형/로그인한 사용자에게는 문제가 되지 않습니다. 일반적인 프로세스 컨텍스트가 제한되지 않아 SELinux 규칙이 적용되지 않기 때문입니다. systemd또는 기타 유사한 메커니즘 에 의해 시작된 모든 데몬~ 할 것이다ps의 옵션 으로 확인할 수 있는 프로세스 컨텍스트를 수신합니다 -Z. SELinux를 실행하는 Debian 시스템의 예:

# ps -Z -p $$
LABEL                             PID TTY          TIME CMD
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 22498 pts/7 00:00:00 bash
# ps -Z -p $(pidof /sbin/getty)
LABEL                             PID TTY      STAT   TIME COMMAND
system_u:system_r:getty_t:s0     6158 tty1     Ss+    0:00 /sbin/getty 38400 tty1
system_u:system_r:getty_t:s0     6159 tty2     Ss+    0:00 /sbin/getty 38400 tty2
system_u:system_r:getty_t:s0     6160 tty3     Ss+    0:00 /sbin/getty 38400 tty3
system_u:system_r:getty_t:s0     6161 tty4     Ss+    0:00 /sbin/getty 38400 tty4
system_u:system_r:getty_t:s0     6162 tty5     Ss+    0:00 /sbin/getty 38400 tty5
system_u:system_r:getty_t:s0     6163 tty6     Ss+    0:00 /sbin/getty 38400 tty6

답변2

예, 주요 차이점이 있습니다.

  • cp는 파일의 복사본을 만듭니다
  • mv(파일 시스템 내에 있는 경우)는 디스크의 일부 포인터를 이동합니다.

다음을 시도해 보세요:

touch a
ls -i a
cp a b
ls -i a b
mv a c
ls -i b c

b는 새 inode 번호를 가진 새 파일이고, c는 이전 a의 inode 번호를 가진 동일한 파일이라는 것을 알 수 있습니다.

하지만 그것만으로는 당신의 이상한 행동이 설명되지 않습니다.

답변3

이것이 바로5월발생합니다(귀하가 애플리케이션이나 이러한 오류에 대한 정보를 거의 공유하지 않으므로 추측만 할 수 있습니다).

리눅스에서필수 파일 잠금은 일반적이지 않습니다.. 다음과 같은 전화flock(2)관리하다자문자물쇠. 이는 커널이 잠금을 추적하지만 강제로 적용하지는 않는다는 의미입니다. 이를 준수하는 것은 애플리케이션에 달려 있습니다.

무언가가 잠겨 fileA있고 애플리케이션이 잠금을 준수하는 경우 서비스가 거부될 수 있습니다. 이런 일이 일어난다고 가정해 봅시다.

잠금은 경로나 이름보다는 inode에 영향을 미칩니다. 잠긴 파일을 단일 파일 시스템 fileA내로 이동(이름 바꾸기)하면 fileBinode에는 아무런 영향도 미치지 않으며 파일은 여전히 ​​잠겨 있고 응용 프로그램은 여전히 ​​작업을 거부합니다. 파일을 복사하면 fileB잠겨 있지 않은 자체 inode가 있는 별도의 파일이 생성되고 애플리케이션이 작동합니다.

(참고: 파일을 다른 파일 시스템으로 이동하는 것은 실제로 복사+삭제이므로 잠금이 해제되어야 합니다.)

관련 정보