우분투에서 'Exec 형식 오류'가 발생하는 이유
공식 apt-get 저장소를 통해 패키지를 설치하는 동안에는 거의 발생하지 않지만, 인터넷에서 직접 내려받은 프로그램을 실행할 때는 bash: ./nameOfProgram: cannot execute binary file: Exec format error라는 당황스러운 오류 메시지를 마주할 수 있습니다. 이 오류 뒤에는 bash: ./nameOfProgram.sh: Permission denied 같은 추가 메시지가 따라오기도 하는데, 이는 우분투가 해당 바이너리 파일과 제대로 통신하지 못했다는 의미입니다.
원인은 간단합니다. 파일 자체는 유효한 리눅스 바이너리이지만, 현재 커널이 지원하는 아키텍처와 다른 칩셋용으로 컴파일되었기 때문입니다. 대부분의 우분투 사용자는 인텔이 개발한 표준 아키텍처 기반의 32비트 또는 64비트 프로세서를 사용하고 있으며, 제조사가 어느 회사든 상관없습니다. 다만 주의할 점은, 64비트 프로세서도 32비트 모드로 동작할 수 있다는 것입니다. 즉, 64비트 CPU를 사용 중인데도 이 오류가 발생한다면 32비트 버전의 우분투를 실행하고 있을 가능성이 있습니다. 몇 가지 간단한 명령어만으로 자신의 시스템 상태를 확인할 수 있습니다.
방법 1: arch 명령어로 아키텍처 확인하기
자신의 머신에 어떤 마이크로프로세서가 장착되어 있는지 잘 모른다면, 터미널에서 arch 명령어부터 실행해 보세요. 이 명령은 한 줄의 출력만 반환합니다. 대부분의 경우 i686이 표시되는데, 이는 32비트 프로세서를 사용 중이라는 뜻이며 x86_64 바이너리는 실행할 수 없습니다. 반대로 amd64 등이 표시된다면 x86_64 프로세서를 사용 중이므로, 이론상 대부분의 32비트 및 64비트 바이너리를 실행할 수 있습니다.
참고로 마이크로소프트 윈도우와 달리, 우분투 리눅스에는 64비트 시스템에서 16비트 윈도우 프로그램까지 구동할 수 있는 도구가 기본적으로 포함되어 있는 경우도 많습니다.
여기서 사용되는 용어는 실제 칩 모델명과 일치하지 않아도 됩니다. 예를 들어 i686은 실제 인텔 80686 칩이 아니더라도 리눅스가 수많은 32비트 프로세서를 지칭하는 방식입니다. 64비트 인텔 기술을 사용 중이더라도 arch 명령이 프로세서를 amd64라고 부를 수 있는데, 이는 오류가 아니므로 걱정할 필요가 없습니다. 정확한 프로세서 종류를 알고 싶다면 cat /proc/cpuinfo 또는 more /proc/cpuinfo 명령을 사용하세요. 이 파일의 행이 길기 때문에 그래픽 터미널 창을 사용한다면 명령 실행 전에 F11 키로 전체 화면을 켜는 것이 좋습니다. 가상 콘솔 사용자, 특히 우분투 서버 환경에서는 크게 신경 쓸 필요가 없습니다.
PowerPC 등 특수 아키텍처라면?
arch 명령이 다른 종류의 출력을 보여줄 수도 있는데, 이 경우 실행 가능한 소프트웨어 선택지가 더 좁아집니다. 우분투는 오랫동안 PowerPC 아키텍처를 지원했으며, 이 아키텍처는 일부 워크스테이션과 클래식 매킨토시, 초기 OS X 맥에서 사용되었습니다. 지금도 해당 아키텍처용 우분투 저장소를 찾을 수 있지만 요즘은 거의 지원되지 않습니다. 이러한 환경에서는 공식 저장소 외부에서 내려받은 리눅스 바이너리를 실행하기 어려울 가능성이 높습니다. 물론 우분투가 이런 기기에서 작동하지 않는다는 뜻은 아니며, 다만 더 가벼운 Lubuntu 배포판을 검토해 보는 것이 좋습니다.
방법 2: file 명령어로 바이너리 유형 확인하기
file 명령어는 파일의 내용을 식별하는 도구로, 매우 정확한 편입니다. 문제가 되는 파일에 대해 file nameOfProgram을 입력하여 출력 결과에 ELF 32-bit 또는 ELF 64-bit가 표시되는지 확인해 보세요. 만약 ELF 64-bit 바이너리라고 알려주는데 앞서 arch 명령 결과가 i686이었다면, 해당 프로그램을 합리적인 방법으로 실행하는 것은 불가능합니다. 반대로 64비트 프로세서에 32비트 우분투를 돌리고 있다면 운영체제를 재설치하는 방법도 있지만, 단일 프로그램 하나를 위해 이런 극단적인 조치를 취하는 것은 비효율적입니다.
터미널에 이상한 문자가 출력될 때
드물지만, 멀웨어 검사까지 마쳤는데도 프로그램 실행 시 터미널에 엉뚱한 문자들이 잔뜩 출력되는 경우가 있습니다. 보통 마름모꼴 블록이나 숫자가 들어간 사각형 형태로 나타나는데, 후자는 일부 컴퓨터 과학자들이 'tofu(두부)'라고 부르는 현상으로, 현재 설치된 글꼴이 표시할 수 없는 유니코드 문자 값을 나타냅니다. 이렇게 출력된다면 폰트 오류도, 멀웨어 감염도 아니니 안심해도 됩니다. 단순히 바이너리 안에 컴파일된 마이크로프로세서 opcode가 시스템에 너무 생소해서 코드 일부를 해석하지 못하는 것뿐입니다.
근본적인 해결책: 올바른 아키텍처용 패키지 설치
가장 확실한 해결 방법은 자신의 아키텍처에 맞는 패키지를 설치하는 것입니다. 우분투 내부에서 패키지를 설치한다면 apt-get 시스템이나 그래픽 기반 Synaptic 관리자가 알아서 처리해 줍니다. 다른 배포판에서 패키지를 내려받는다면 자신의 아키텍처에 맞는 버전을 직접 찾아야 합니다. 예를 들어 Arch Linux의 gvim 패키지 목록을 보면, 기본 패키지는 x86_64 아키텍처용이지만 i686 칩셋용 패키지도 함께 제공됩니다. i686용은 인텔 인터럽트 구조를 따르는 32비트 머신에서 작동합니다. 단, i686과 32비트가 항상 같은 의미는 아니라는 점을 기억하세요. 리눅스가 지원하는 다른 칩셋들 역시 자체적인 32비트 구현을 갖고 있습니다.
GNU/Linux 생태계를 깊이 탐색하다 보면 이보다 훨씬 이질적인 기술용으로 컴파일된 바이너리를 접하게 될 수도 있습니다. 리눅스는 진정한 크로스 플랫폼 환경이기 때문에 OpenRISC, MIPS, SPARC, M32R, MN103, ARM, ARC, Alpha 등 수많은 표준 아키텍처용 바이너리가 존재합니다. 대부분은 실행할 수 없겠지만, ARM은 태블릿과 스마트폰에서 널리 쓰이는 매우 인기 있는 플랫폼이며 라즈베리 파이(Raspberry Pi)의 기반 아키텍처이기도 합니다. 따라서 모바일 기기에서 우분투를 실행하거나 라즈베리 파이용 Ubuntu MATE 배포판을 사용한다면, 인텔 32비트나 x86_64 바이너리 대신 ARM용 패키지가 필요합니다.