나는 bash 스크립트를 작성했고 먼저 컴파일하지 않고 실행했습니다. 그것은 아주 잘 작동합니다. 권한이 있든 없든 작동하지만 C 프로그램의 경우 소스 코드를 컴파일해야 합니다. 왜?
답변1
이는 쉘 스크립트가 컴파일되지 않고 해석된다는 것을 의미합니다. 쉘은 한 번에 하나의 명령을 해석하고 매번 각 명령을 실행하는 방법을 파악합니다. 어쨌든 쉘 스크립트는 대부분의 시간을 다른 프로그램을 실행하는 데 소비하기 때문에 이는 쉘 스크립트에 적합합니다.
반면에 C 프로그램은 일반적으로 컴파일됩니다. 실행하기 전에 컴파일러는 해당 프로그램을 완전히 기계어 코드로 완전히 변환합니다. 과거에도 C 인터프리터가 있었습니다(예:하이소프트 소프트웨어Atari ST의 C 인터프리터)이지만 매우 특이합니다. 오늘날 C 컴파일러는 매우 빠릅니다.TCC#!/usr/bin/tcc -run
매우 빠르기 때문에 shebang을 사용하여 "C 스크립트"를 생성하는 데 사용할 수 있습니다.할 수 있는(사용자 관점에서) 쉘 스크립트와 동일한 방식으로 실행되는 C 프로그램을 작성하십시오.
일부 언어에는 해석기와 컴파일러가 모두 있는 경우가 많습니다. BASIC이 떠오르는 한 가지 예입니다.
소위 쉘 스크립트 컴파일러도 찾을 수 있지만 내가 본 것은 난독화된 래퍼일 뿐입니다. 그들은 여전히 스크립트를 실제로 해석하기 위해 쉘을 사용합니다. ~처럼추적 장치적절한 쉘 스크립트 컴파일러가 확실히 가능하기는 하지만 그다지 흥미롭지는 않다는 점을 지적합니다.
또 다른 생각은 쉘의 스크립트 해석 기능이 명령줄 처리 기능의 확장이므로 자연스럽게 해석 접근 방식으로 이어진다는 것입니다. 반면에 C는 독립 실행형 바이너리를 생성하도록 설계되었으며 이로 인해 컴파일 방식이 사용되었습니다. 일반적으로 컴파일된 언어는 인터프리터나 최소한 명령줄 파서(REPL이라고 함)를 생성하는 경향이 있습니다.읽기-평가-인쇄 루프; 쉘 자체는 REPL입니다.
답변2
이 모든 것은 인간이 읽고 쓰는 프로그램이 컴퓨터가 이해할 수 있는 기계 명령어로 변환되는 방식 사이의 기술적 차이로 귀결됩니다. 그리고 각 접근 방식의 서로 다른 장단점은 일부 언어를 작성하려면 컴파일러가 필요하고 일부는 해석을 위해 필요하며 작성되는 이유입니다. .
1. 기술적인 차이점
(참고: 이 문제를 해결하기 위해 여기에서 많은 단순화를 수행했습니다. 더 깊은 이해를 위해 내 답변 하단의 기술 노트가 여기에서 일부 단순화를 자세히 설명/정제하고 이 답변에 대한 의견도 도움이 되었습니다. . 설명과 토론..)
프로그래밍 언어에는 기본적으로 두 가지 광범위한 범주가 있습니다.
- 다른 프로그램("컴파일러")은 프로그램을 읽고 코드가 수행할 단계를 결정한 다음새로운 프로그램을 작성하다이러한 단계를 수행하는 기계어 코드(컴퓨터 자체가 이해하는 "언어")에서.
- 다른 프로그램("인터프리터")은 프로그램을 읽고 코드가 수행할 단계를 결정한 다음다음 단계를 직접 따르세요.. 새로운 프로그램이 생성되지 않습니다.
C는 첫 번째 범주에 속합니다(C번역가C 번역언어컴퓨터로 들어가세요기계어 코드: 기계어 코드는 파일에 저장되며, 해당 기계어 코드를 실행하면 원하는 작업이 수행됩니다.
bash는 두 번째 범주에 속합니다(bash통역사배쉬 읽기언어그리고 카니발통역사원하는 대로 수행됩니다. 따라서 "컴파일러 모듈" 자체는 없으며 인터프리터는 해석 및 실행을 담당하고 컴파일러는 읽기 및 번역을 담당합니다.
이것이 무엇을 의미하는지 눈치채셨을 것입니다:
C를 사용하면 "설명" 단계를 수행합니다.한 번, 그러면 프로그램을 실행해야 할 때마다 컴퓨터에 기계어 코드를 실행하라고 지시하기만 하면 됩니다. 컴퓨터는 추가로 "생각"할 필요 없이 프로그램을 실행할 수 있습니다.
Bash를 사용하려면 "설명" 단계를 수행해야 합니다.매번프로그램을 실행하면 컴퓨터가 bash 인터프리터를 실행하고 있고 bash 인터프리터는 각 명령에 대해 수행해야 할 작업을 파악하기 위해 매번 추가 "사고"를 수행합니다.
따라서 C 프로그램은 준비(컴파일 단계)에 더 많은 CPU, 메모리 및 시간이 필요하지만 실행하는 데는 더 적은 시간과 작업이 필요합니다. Bash 프로그램은 준비하는 데 더 적은 CPU, 메모리 및 시간이 필요하지만 실행하는 데는 더 많은 시간과 작업이 필요합니다. 요즘 컴퓨터가 너무 빠르기 때문에 대부분의 경우에는 차이를 느끼지 못할 것입니다. 그러나 이는 확실히 차이를 가져오고 크거나 복잡한 프로그램 또는 많은 작은 프로그램을 실행해야 할 때 그 차이가 커집니다.
또한 C 프로그램은 컴퓨터의 기계어("네이티브 언어")로 변환되므로 다른 기계어(예: Intel 64비트에서 Intel 32비트) 비트를 사용하는 다른 컴퓨터로 프로그램을 복사할 수 없습니다. 또는 Intel에서 ARM이나 MIPS 등으로). 다른 기계 언어로 컴파일하는 데 시간을 소비해야 합니다.다시. 그러나 bash 프로그램은 bash 인터프리터가 설치된 다른 컴퓨터로 이동할 수 있으며 정상적으로 실행됩니다.
지금왜질문의 일부
수십 년 전, C 개발자들은 현대 표준의 제약을 받는 하드웨어에 운영 체제와 기타 프로그램을 작성했습니다. 여러 가지 이유로 프로그램을 컴퓨터용 기계어 코드로 변환하는 것이 당시에는 이러한 목표를 달성하는 가장 좋은 방법이었습니다. 게다가 그들이 하는 작업은 그들이 작성한 코드가 실행되기 위해 중요합니다.효율적인.
Bourne 쉘과 bash 제작자는 정반대를 원했습니다. 즉, 즉시 실행될 수 있는 프로그램/명령을 작성하기를 원했습니다. 명령줄, 터미널에서 한 줄, 명령만 작성하면 됩니다. 그들은 당신이 작성한 스크립트가 쉘 해석기/프로그램이 설치된 곳 어디에서나 작동하기를 원합니다.
결론적으로
간단히 말해서, bash 컴파일러는 필요하지 않지만 C 컴파일러는 필요합니다. 왜냐하면 이러한 언어는 실제 컴퓨터 작업을 다양한 방식으로 변환하고, 이러한 언어는 목표가 다르기 때문에 다양한 실행 옵션이 선택되기 때문입니다.
추가 기술/고급 세부정보/참고 사항
실제로 C를 만들 수 있습니다.통역사, 또는 카니발번역가. 이러한 가능성을 막을 수 있는 것은 없습니다. 단지 이러한 언어가 다른 목적으로 만들어졌을 뿐입니다. 복잡한 프로그래밍 언어에 대해 좋은 해석기나 컴파일러를 작성하는 것보다 다른 언어로 프로그램을 다시 작성하는 것이 더 쉬운 경우가 많습니다. 특히 해당 언어가 잘하는 특정 기능이 있고 애초에 특정 방식으로 작동하도록 설계된 경우에는 더욱 그렇습니다. C는 컴파일 가능하도록 설계되었으므로 대화형 셸에 필요한 편리한 속기가 많이 부족하지만 매우 구체적이고 낮은 수준의 데이터/메모리 작업과 운영 체제와의 상호 작용을 표현하는 데 적합합니다. 효율적으로 컴파일된 코드를 작성하다 보면 이러한 작업을 수행하는 자신을 발견하게 될 것입니다. 동시에 bash는 다른 프로그램을 실행하고, 파일/파일 설명자를 리디렉션하고, 텍스트 문자열을 조작하는 데 매우 능숙하며, 대화형 셸에서 자주 수행하려는 작업이기 때문에 이러한 프로그램을 편리하게 단축할 수 있습니다.
고급 세부 정보: 실제로 두 가지 유형이 혼합된 일부 프로그래밍 언어가 있습니다(이 언어는 소스 코드를 "대부분" 번역하여 대부분의 해석/"생각"을 한 번 수행하고 약간의 해석만 수행함) 나중에 /"생각해 보세요"). Java, Python 및 기타 많은 최신 언어는 실제로 하이브리드입니다. 이들은 해석된 언어의 이식성 및/또는 신속한 개발 이점과 컴파일된 언어의 속도를 제공하려고 노력합니다. 이러한 방법을 결합하는 방법에는 여러 가지가 있으며, 언어에 따라 이를 다르게 수행합니다. 이 주제를 더 깊이 탐구하고 싶다면 "바이트코드"로 컴파일하는 프로그래밍 언어에 대해 읽어볼 수 있습니다. 및 "JIT"(Just-in-time 컴파일, 프로그램이 해석되거나 실행되는 동안 프로그램을 컴파일하거나 재컴파일할 수도 있음).
실행 가능 비트에 대해 질문하셨습니다. 실제로 실행 가능 비트는 운영 체제에 파일이 있음을 알려줍니다.허용하다처형되었다. 나는 bash 스크립트가 당신을 위해 작동하는 유일한 이유가 없다고 생각합니다.구현하다권한은 실제로 bash 쉘 내부에서 실행하기 때문에 발생합니다. 일반적으로 운영 체제는 실행 비트가 설정되지 않은 파일을 실행하라는 요청을 받으면 단순히 오류를 반환합니다. 그러나 Bash와 같은 일부 쉘은 해당 오류를 확인하고 기본적으로 운영 체제가 일반적으로 수행하는 단계(파일 시작 부분에서 "#!" 줄을 찾아 시도)를 자체적으로 시뮬레이션하여 파일을 해석하기 위해 프로그램 자체를 실행합니다
/bin/sh
. "#!" 줄이 없습니다.때로는 컴파일러가 시스템에 이미 설치되어 있고 때로는 IDE가 자체 컴파일러와 함께 제공되거나 컴파일을 실행하는 경우도 있습니다. 이로 인해 컴파일된 언어가 컴파일되지 않은 언어처럼 "느껴질" 수 있지만 기술적인 차이점은 그대로 유지됩니다.
"컴파일된" 언어가 반드시 기계어 코드로 컴파일되는 것은 아니며 전체 컴파일 자체가 하나의 주제입니다. 기본적으로 이 용어는 매우 광범위하게 사용됩니다. 실제로 몇 가지 사항을 나타낼 수 있습니다. 특정한 의미에서 "컴파일러"는 한 언어(보통 사람이 사용하기 쉬운 "고수준" 언어)를 다른 언어(보통 컴퓨터가 사용하기 쉬운 "저수준" 언어)로 번역하는 역할을 합니다. 사용) -때때로 자주는 아니지만 이것은 기계어 코드입니다). 또한 때때로 사람들이 "컴파일러"라고 말할 때 실제로는 함께 작동하는 여러 프로그램에 대해 이야기하고 있습니다(일반적인 C 컴파일러의 경우 실제로는 "전처리기", 컴파일러 자체, "어셈블러" 및 "링커"의 네 가지 프로그램입니다).
답변3
다음 프로그램을 고려해보세요:
2 Mars Bars
2 Milks
1 Bread
1 Corn Flakes
그나저나 bash
, 당신은 화성 바를 찾기 위해 가게를 돌아다니고, 결국 그것을 발견하고, 우유 등을 찾기 위해 돌아다닙니다. 이는 빵을 볼 때 빵과 쇼핑의 다른 모든 복잡한 사항을 인식할 수 있는 Experienced Shopper라는 정교한 프로그램을 실행하고 있기 때문에 가능합니다. bash
상당히 복잡한 절차입니다.
또는 쇼핑 목록을 쇼핑 편집자에게 넘겨줄 수도 있습니다. 컴파일러는 잠시 생각한 후 새로운 목록을 제공합니다. 이 목록은긴이지만 더 간단한 지침이 포함되어 있습니다.
... lots of instructions on how to get to the store, get a shopping cart etc.
move west one aisle.
move north two sections.
move hand to shelf three.
grab object.
move hand to shopping cart.
release object.
... and so on and so forth.
보시다시피 컴파일러는 모든 것이 저장소의 어디에 있는지 정확히 알고 있으므로 전체 "물건 찾기" 단계가 필요하지 않습니다.
이는 그 자체로 하나의 절차이며 수행하는 데 "숙련된 쇼핑객"이 필요하지 않습니다. 필요한 것은 "기본적인 인간 운영 체제"를 갖춘 인간뿐입니다.
컴퓨터 프로그램으로 돌아가서: bash
"숙련된 쇼핑객"이 되면 스크립트를 가져와 아무것도 컴파일하지 않고 직접 실행할 수 있습니다. AC 컴파일러는 실행하는 데 더 이상 도움이 필요하지 않은 독립 실행형 프로그램을 생성합니다.
인터프리터와 컴파일러 모두 고유한 장점과 단점이 있습니다.
답변4
영어가 귀하의 모국어가 아니라고 상상해 보십시오(영어가 귀하의 모국어가 아닌 경우 이는 쉬울 수 있습니다).
이 글은 3가지 방법으로 읽을 수 있습니다:
- (통역) 읽을 때 보이는 모든 단어를 번역하세요.
- (최적화-설명) 일반적인 문구(예: "귀하의 모국어")를 찾아 번역하고 적어보세요. 그런 다음 이미 번역한 문구를 제외하고 각 단어를 번역하세요.
- (편집됨) 다른 사람에게 전체 답변을 번역해 달라고 요청하세요.
컴퓨터에는 프로세서가 이해하는 지침과 운영 체제(예: Windows, Linux, OSX 등)가 이해하는 지침의 조합인 일종의 "모국어"가 있습니다. 이 언어는 사람이 읽을 수 없습니다.
Bash와 같은 스크립팅 언어는 일반적으로 첫 번째와 두 번째 범주에 속합니다. 한 번에 한 줄씩 읽고, 그 줄을 번역하고 실행한 후, 다음 줄로 넘어갑니다.Mac 및 Linux에서는 Bash, Python 및 Perl과 같은 다양한 언어에 대해 꽤 많은 인터프리터가 기본적으로 설치됩니다. Windows에서는 직접 설치해야 합니다.
많은 스크립팅 언어는 일부 사전 처리를 수행합니다. 그렇지 않으면 애플리케이션 속도를 저하시킬 수 있는 자주 실행되는 코드 블록을 컴파일하여 실행 속도를 높이려고 합니다. 여러분이 들어보셨을 수 있는 일부 용어에는 AOT(Ahead-of-Time) 또는 JIT(Just-In-Time) 컴파일이 포함됩니다.
마지막으로, 컴파일된 언어(예: C)는 프로그램을 실행하기 전에 전체 프로그램을 번역합니다. 이것의 장점은 번역이 다른 기계에서 실행될 수 있다는 것입니다. 따라서 프로그램을 사용자에게 넘겨줄 때 여전히 오류가 있을 수 있지만 여러 유형의 오류를 이미 지울 수 있습니다. 내가 말했듯이 이것을 번역가에게 주면 garboola mizene resplunks
이것이 당신에게는 유효한 영어처럼 보일 수 있지만 번역자는 내가 말도 안되는 말을 하고 있다고 말할 수 있습니다.컴파일된 프로그램을 실행할 때 인터프리터가 필요하지 않습니다. 이미 컴퓨터의 모국어이기 때문입니다.
그러나 컴파일된 언어에는 단점이 있습니다. 컴퓨터에는 하드웨어와 운영 체제의 기능으로 구성된 모국어가 있다고 언급했습니다. 음, Windows에서 프로그램을 컴파일하는 경우 컴파일된 프로그램이 다음을 기대하지 않습니다. Windows Mac에서 실행됩니다. 일부 언어는 피진 영어와 약간 유사한 중간 언어로 컴파일하여 이 문제를 해결합니다. 이렇게 하면 컴파일된 언어의 이점과 약간의 속도 증가를 얻을 수 있지만 이는 코드를 번들로 묶어야 함을 의미합니다. 통역사 사용(또는 설치된 통역사 사용).
마지막으로 IDE가 파일을 컴파일하고 코드를 실행하기 전에 오류를 알려줄 수 있습니다. 때때로 이 오류 검사는 컴파일러가 수행하는 것보다 더 깊이 있을 수 있습니다. 컴파일러는 일반적으로 합리적인 네이티브 코드를 생성하는 데 필요한 만큼만 확인합니다. IDE는 종종 몇 가지 추가 검사를 실행하여 예를 들어 변수를 두 번 정의했는지 또는 사용하지 않은 항목을 가져왔는지 알려줄 수 있습니다.