UTF8 문자로 인해 파일에 액세스할 수 없게 됩니다.

UTF8 문자로 인해 파일에 액세스할 수 없게 됩니다.

내가 실행하면 :

scp [email protected]:/home/me/cömmön_file.jpg /home/me/

내 원격 서버에서 다음을 얻습니다.

scp:/home/me/cömmön_file.jpg: 해당 파일이나 디렉터리가 없습니다

utf8 문자를 와일드카드로 바꾸면 작동합니다.

scp [email protected]:/home/me/c?mm?n_file.jpg /home/me/

그리고/또는

scp [email protected]:/home/me/c*mm*n_file.jpg /home/me/

원격 시스템에서 AWS CLI를 사용하는 경우에도 이 동작이 복제됩니다.

원격 컴퓨터에서 명시적인 이름을 사용하여 다른 명령을 실행하면 예상대로 작동합니다.

예를 들어

ls -lha /home/me/cömmön_file.jpg

-rw-r--r--. 1 我我1.1M 1월 15일 21:58 /home/me/cömmön_file.jpg

파일 이름 바꾸기를 사용할 수도 있습니다 mv.

파일 전송 문제입니까, 아니면 파일을 호스팅하는 컴퓨터의 근본적인 문제입니까?

현재 문제를 일으키는 UTF8 문자는 다음과 같습니다.https://www.compart.com/en/unicode/U+0308하지만 이 문제는 다른 캐릭터에서도 재현될 것으로 예상됩니다. 파일 이름 ö을 바꾸려고하면https://www.compart.com/en/unicode/U+00F6내 컴퓨터는 파일이 동일하다고 알려줍니다.

mv: '/home/me/cömmön_file.jpg'와 '/home/me/cömmön_file.jpg'는 동일한 파일입니다.

이 파일을 호스팅하는 서버는 다음과 같습니다.

NAME="CentOS Linux"
VERSION="7 (Core)"

그것은 locale:

LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

파일을 요청하는 서버는 다음과 같습니다.

NAME="Amazon Linux"
VERSION="2"

그것은 locale:

LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

답변1

scp빠른 수정: 키보드에서 악센트 문자를 사용하는 대신 탭 완성을 사용하거나(네트워크 등 을 통해 탭을 사용할 수 있도록 SSH 키를 설정 rsync), 일반적인 예상 동작이므로 와일드카드로 대체하세요.


이것은 작동하지 않습니다. 왜냐하면동일한 파일 이름을 입력하지 않았습니다..

미친 것 같나요? 이것은 UTF-8입니다.

더 미친 짓: 나는 내 것을 사용할 수 있다원격 마음 읽기의 마법 같은 영적 힘너한테 하나 있다고 말해줘애플 컴퓨터.

더 심각하게 말하면, 이는 질문할 때 제공하는 것을 잊었지만 질문 자체를 입력할 때 실수로 공개한 중요한 정보입니다.


위의 답변을 복사하여 붙여넣을 때:

# echo "scp [email protected]:/home/me/cömmön_file.jpg" | hexdump -C
00000000  73 63 70 20 6d 65 40 65  78 61 6d 70 6c 65 2e 63  |scp [email protected]|
00000010  6f 6d 3a 2f 68 6f 6d 65  2f 6d 65 2f 63 6f cc 88  |om:/home/me/co..|
00000020  6d 6d 6f cc 88 6e 5f 66  69 6c 65 2e 6a 70 67 20  |mmo..n_file.jpg |
00000030  2f 68 6f 6d 65 2f 6d 65  2f 0a                    |/home/me/.|
0000003a

문자 "ö"가 어떻게 인코딩되는지 주의 깊게 살펴보세요 6f cc 88. 문자 "o" 뒤에 추가 UTF-8 코드 포인트가 옵니다. (실제로 내 터미널에서는 "ö"로 표시되지 않고 "o"로 표시됩니다)

나(=Linux 사용자)가 다음을 입력할 때:

echo /home/me/cömmön_file.jpg | hexdump -C
00000000  2f 68 6f 6d 65 2f 6d 65  2f 63 c3 b6 6d 6d c3 b6  |/home/me/c..mm..|
00000010  6e 5f 66 69 6c 65 2e 6a  70 67 0a                 |n_file.jpg.|
0000001b

"ö" 기호를 다시 자세히 살펴보십시오. c3 b6이는 완전히 다른 UTF-8 코드 포인트이며 추가 ASCII 문자가 없습니다.


매우 간단한 설명:UTF-8 정규화(합성 및 분해).


더 자세한 설명:

유니코드에는 "ö"와 같은 것을 인코딩하는 여러 가지 방법이 있습니다.

  • 첫 번째 방법은캐릭터로 구성: Latin-1(ISO/IEC 8859-1:1998) 코드 포인트, 유니코드 코드 포인트 U+00f6(UTF-8에서 c3 b6으로 인코딩됨)에서 상속된 코드 포인트 "ö"가 있습니다.
  • 두 번째 방법은분해된 문자: 먼저 ASCII o를 출력한 다음 특수 코드 포인트를 추가합니다.이 말은'앞의 문자에 발음 구별 부호를 추가하세요', 유니코드 코드 포인트 U+0308(UTF-8에서 cc 88로 인코딩됨)

̫cra̎zyshit̫ke̬̓ke̬̓king̬̓king̬̓KITHIPAIL, ̌m̳͌̽m̳͌̽a̪ͥd̺͑n͕͌̐e̿͊s͇s̘͓͊을 모두 할 수 있게 해주는 것이 바로 이 조합입니다.

흡입.

나머지 지역에서는 가능하면 결합 문자를 사용하고(더 컴팩트하고 Latin-1 호환 유니코드 범위를 사용하여 이전 버전과의 호환성을 단순화하기 때문에) 결합 문자가 없는 항목에 대해서만 결합 문자를 사용합니다. 자체 코드 포인트(주로 덜 일반적인 언어용)

Apple은 분명히 다른 행성에 살고 있으며 항상 캐릭터를 사용하기로 결정했습니다(그들은 어둠의 Za를 숭배하기 때문에 ͓̙̘͌l̦̖͉ ̀ͦ͆͊ͧ̀g ͖̭̼̗͉̦̬̍̀̌ͬ̓ͥЂ̧͉̗̱̥̣̯͍̗̲̩͑̈́͐ ̓͘ ͡?).

"ö"와 같은 키보드 문자를 입력해도 키를 입력하는 컴퓨터에 따라 동일한 이진 시퀀스가 ​​생성되지 않습니다.

그런 다음 또 다른 문제가 발생합니다. 대부분의 Unix는 대소문자를 구분하고 유니코드 인코딩(UTF-8 지원)에 민감한 파일 시스템(예: Linux의 EXT4)을 사용하는 경향이 있습니다. 그들은 텍스트가 쓰여졌는지 아닌지를 보존하려고 노력합니다. 따라서 동일한 최종 결과 "ö"를 인코딩 6f cc 88하더라도 UTF-8 바이너리 시퀀스를 구별합니다. c3 b6(같은 라틴 문자라도 "A"와 "a"를 같은 방식으로 구별합니다.) 따라서 키보드에서 생성된 "ö"는 서버에서 생성된 "ö"와 동일하지 않습니다.

스택 교환은 사용자가 입력한 유니코드 인코딩을 그대로 저장하여 비밀스러운 답변을 제공합니다.HTML 정규식 파서그것들. (그래서 Mac은 "ö"에 대한 특정 바이트 시퀀스를 기록하여 자신을 배신했습니다.)

관련 정보