리눅스에서 파일 시스템 문자 인코딩에 대한 몇 가지 질문


12

Windows ( GBK 인코딩)와 Linux ( UTF-8 인코딩) 간에 많은 파일 교환 작업으로 인해 다음 과 같은 문자 인코딩 문제가 쉽게 발생합니다.

  • Windows 시스템에서 이름에 중국어 문자가 포함 된 zip / tar 파일은 Linux 시스템에서 압축을 풀거나 해제하십시오.
  • GBK 인코딩 이름의 파일을 디스크에 쓰는 마이그레이션 된 레거시 Java 웹 애플리케이션 (JSP에서 GBK 인코딩을 사용하여 Windows 시스템에서 설계)을 실행합니다.
  • ftp는 Windows FTP 서버와 Linux 클라이언트간에 GBK 인코딩 이름의 파일을 가져 오거나 입력합니다.
  • Linux에서 LANG 환경을 전환하십시오.

앞에서 언급 한 일반적인 문제는 파일 찾기 / 이름 지정입니다. googled 후 Linux에서 유니 코드 사용 기사 http://www.linux.com/archive/feed/39912를 얻었습니다 .

운영 체제 및 많은 유틸리티는 파일 이름의 바이트가 나타내는 문자를 인식하지 못합니다.

따라서 다른 인코딩으로 2 개의 中文 .txt 파일을 가질 수 있습니다.

[root@fedora test]# ls
????  中文
[root@fedora test]# ls | iconv -f GBK
中文
涓iconv: illegal input sequence at position 7
[root@fedora test]# ls 中文 && ls $'\xd6\xd0\xce\xc4'|iconv -f gbk
中文
中文

질문 :

  1. LANG / LC_ALL 환경에 관계없이 Linux 파일 시스템에서 고정 문자 인코딩 ( NTFS에서 UTF-16을 내부적으로 사용)을 사용하여 파일 이름을 저장 하도록 구성 할 수 있습니까?
  2. 또는 실제로 물어보고 싶은 것은 : $'\xe4\xb8\xad\xe6\x96\x87.txt'zh_CN.UTF-8 환경에서 파일 이름 中文 .txt ( $'\xd6\xd0\xce\xc4.txt')를 허용하고 zh_CN.GBK 환경에서 파일 이름 中文 .txt ( ) 가 동일한 파일을 참조하도록 할 수 있습니까?
  3. 구성 할 수 없다면 커널을 패치하여 파일 시스템과 현재 환경간에 문자 인코딩을 번역 할 수 있습니까 (구현이 아닌 질문 일뿐입니다)? 가능한 경우 성능에 얼마나 영향을 미칩니 까?

파일 시스템의 UTF-16 인코딩과 로케일 설정에 지정된 인코딩간에 자동으로 변환되는 Cygwin 1.7을 사용하여 Windows 측에서 문제점을 해결할 수 있습니다. 기본값은 UTF-8이므로 Cygwin tar는 파일 이름을 UTF-8로 인코딩합니다.
ak2

@ ak2 감사합니다. Cygwin은 정말 좋습니다. 몇 년 동안 사용해 왔습니다. tar / zip 사례는 단지 예일뿐입니다. 실제 환경에서 zip / tar 파일은 다른 사람이 만들 수 있습니다 (예 : 인터넷에서 파일 다운로드).
LiuYan 刘 研

답변:


8

질문을 순서대로 읽을 때 분명하게 드러나야 할 이유로 귀하의 질문을 약간 재구성했습니다.

1. LANG / LC_ALL 환경에 관계없이 Linux 파일 시스템에서 고정 문자 인코딩을 사용하여 파일 이름을 저장하도록 구성 할 수 있습니까?

아니오, 이것은 가능하지 않습니다. 질문에서 언급했듯이 UNIX 파일 이름은 일련의 바이트 일뿐입니다. 커널은 인코딩에 대해 전혀 알지 못하며, 이는 완전히 사용자 공간 개념입니다.

다시 말해, 커널은 LANG/ LC_*에 대해 아무것도 모르므로 번역 할 수 없습니다.

2. 다른 파일 이름으로 같은 파일을 참조 할 수 있습니까?

동일한 파일을 참조하는 여러 디렉토리 항목이있을 수 있습니다. 하드 링크심볼릭 링크 를 통해이를 만들 수 있습니다 .

그러나 현재 인코딩에서 유효하지 않은 파일 이름 (예 : UTF-8 로케일에서 작업 할 때 GBK 문자열)은 전혀 표시되지 않습니다.

3. 파일 시스템과 현재 환경 사이에서 문자 인코딩을 변환하기 위해 커널을 패치 할 수 있습니까?

커널 을 패치 하여이 작업을 수행 할 수는 없지만 (1 참조) 이론적으로 C 라이브러리 (예 : glibc)를 패치하여이 변환을 수행하고 커널을 호출 할 때 항상 파일 이름을 UTF-8로 변환 할 수 있습니다. 커널에서 파일 이름을 읽을 때 현재 인코딩으로 다시 변환합니다.

더 간단한 방법은 FUSE를 사용 하여 오버레이 파일 시스템을 작성하는 것입니다. 파일 시스템 요청을 UTF-8로 /에서 UTF-8로 변환 한 후 파일 시스템 요청을 다른 위치로 리디렉션합니다. 이상적으로는이 파일 시스템을 마운트 할 수 ~/trans및 액세스하려고 할 때 ~/trans/a/GBK/encoded/path다음 FUSE 파일 시스템은 정말 액세스 /a/UTF-8/encoded/path.

그러나 이러한 접근 방식의 문제점은 파일 시스템에 이미 존재하고 UTF-8로 인코딩되지 않은 파일로 무엇을합니까? 번역하지 않은 채로 전달할 수는 없습니다. 변환 방법을 모르기 때문입니다. ?충돌을 일으킬 수 있기 때문에 유효하지 않은 문자 시퀀스를 번역하여 엉망으로 만들 수는 없습니다 ...


4
이러한 오버레이 파일 시스템이 존재합니다 : Convmvfs .
Gilles 'SO- 악마 그만'

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.