私はbashスクリプトを書いて、最初にコンパイルせずに実行しました。それは非常にうまく動作します。権限があるかどうかは動作しますが、Cプログラムの場合はソースコードをコンパイルする必要があります。なぜ?
答え1
これは、シェルスクリプトがコンパイルされずに解釈されることを意味します。シェルは一度に1つのコマンドを解釈し、毎回各コマンドを実行する方法を理解します。とにかく、シェルスクリプトはほとんどの時間を他のプログラムの実行に費やすので、これはシェルスクリプトに適しています。
一方、Cプログラムは通常コンパイルされます。実行する前に、コンパイラはそのプログラムを完全に機械語コードに完全に変換します。過去にもCインタプリタがありました(例:ハイソフトソフトウェアAtari STのCインタプリタ)ですが、とても珍しいです。今日、Cコンパイラは非常に高速です。TCC#!/usr/bin/tcc -run
非常に高速なので、shebangを使用して「Cスクリプト」を生成するために使用できます。できる(ユーザーの観点から)シェルスクリプトと同じ方法で実行されるCプログラムを作成します。
一部の言語にはソルバーとコンパイラの両方があることがよくあります。 BASICが思い浮かぶ一例です。
いわゆるシェルスクリプトコンパイラも見つけることができますが、私が見たのは難読化されたラッパーです。彼らはまだスクリプトを実際に解釈するためにシェルを使用しています。 〜のように追跡装置適切なシェルスクリプトコンパイラは間違いなく可能ですが、それほど面白くないことを指摘しています。
別の考え方は、シェルのスクリプト解析機能がコマンドライン処理機能の拡張であるため、自然に解析アプローチにつながることです。一方、C はスタンドアロンのバイナリを生成するように設計されており、これによりコンパイル方式が使用されました。一般に、コンパイルされた言語はインタプリタまたは少なくともコマンドラインパーサ(REPLと呼ばれる)を生成する傾向があります。読み取り - 評価 - 印刷ループ;シェル自体はREPLです。
答え2
これらすべては、人間が読み書きするプログラムがコンピュータが理解できる機械命令に変換される方法の間の技術的な違いに帰結します。そして、各アプローチの異なる長所と短所は、いくつかの言語を書くためにコンパイラが必要であり、いくつかは解釈のために必要であり、書かれる理由です。 。
1.技術的な違い
(注:この問題を解決するために、ここで多くの単純化を行いました。より深い理解のために、私の答えの下のテクニカルノートはここでいくつかの単純化を詳細に説明/整理し、この答えに対するコメントも役に立ちました。説明と議論..)
プログラミング言語には、基本的に2つの広範なカテゴリがあります。
- 他のプログラム(「コンパイラ」)はプログラムを読み、コードが実行するステップを決定し、新しいプログラムを書くこれらの手順を実行する機械語コード(コンピュータ自体が理解する「言語」)で。
- 他のプログラム(「インタプリタ」)はプログラムを読み、コードが実行するステップを決定し、次の手順に従います。。新しいプログラムは生成されません。
Cは最初のカテゴリに属します(C翻訳者C 翻訳言語コンピュータに入る機械語コード: 機械語コードはファイルに保存され、対応する機械語コードを実行すると目的のタスクが実行されます。
bashは2番目のカテゴリに属します(bash通訳バッシュを読む言語そしてカーニバル通訳必要に応じて行われます。したがって、「コンパイラモジュール」自体はなく、インタプリタは解釈と実行を担当し、コンパイラは読み取りと翻訳を担当します。
これが何を意味するのか気づいたでしょう:
Cを使用すると、「説明」ステップが実行されます。一度その後、プログラムを実行するたびにコンピュータに機械語コードを実行するように指示するだけです。コンピュータは、さらに「考える」必要なしにプログラムを実行できます。
Bashを使用するには、「説明」ステップを実行する必要があります。毎回プログラムを実行すると、コンピュータはbashインタプリタを実行しており、bashインタプリタは各コマンドに対して何をすべきかを把握するために毎回追加の「事故」を実行します。
したがって、Cプログラムは準備(コンパイルステップ)にはより多くのCPU、メモリ、および時間が必要ですが、実行するには少ない時間と作業が必要です。 Bashプログラムは、準備には少ないCPU、メモリ、および時間が必要ですが、実行するにはより多くの時間と作業が必要です。最近、コンピュータが速すぎるため、ほとんどの場合、違いは感じられません。しかし、これは確かに違いをもたらし、大きなプログラムや複雑なプログラム、または多くの小さなプログラムを実行する必要がある場合、その違いが大きくなります。
さらに、Cプログラムはコンピュータの機械語(「ネイティブ言語」)に変換されるため、他の機械語(Intel 64ビットからIntel 32ビットなど)ビットを使用する他のコンピュータにプログラムをコピーすることはできません。またはIntelからARMやMIPSなど)別の機械語にコンパイルするのに時間を費やす必要があります。再び。ただし、bashプログラムはbashインタプリタがインストールされている他のコンピュータに移動でき、通常どおり実行されます。
今なぜ質問の一部
数十年前、C開発者は、現代標準の制約を受けるハードウェアにオペレーティングシステムやその他のプログラムを作成しました。さまざまな理由で、プログラムをコンピュータの機械語コードに変換することは、当時、この目標を達成するための最良の方法でした。さらに、彼らがすることは、彼らが書いたコードが実行されるために重要です。効率的な。
Bourneシェルとbashメーカーは正反対を望んでいました。つまり、すぐに実行できるプログラム/コマンドを作成したいと思いました。コマンドライン、ターミナルで1行、コマンドを作成するだけです。彼らはあなたが書いたスクリプトがシェルソルバー/プログラムがインストールされているどこでも動作することを望みます。
結論として
簡単に言えば、bashコンパイラは必要ありませんが、Cコンパイラは必要です。なぜなら、これらの言語は実際のコンピュータタスクをさまざまな方法で変換します。
追加技術/高度な詳細/注意事項
実際にCを作ることができます。通訳、またはカーニバル翻訳者。これらの可能性を防ぐことはできません。ただ、これらの言語は他の目的で作られただけです。複雑なプログラミング言語に適したソルバーやコンパイラを書くよりも、他の言語でプログラムを書き換える方が簡単です。特に、その言語がうまく機能する特定の機能があり、もともと特定の方法で動作するように設計されている場合は、さらにそうです。 Cはコンパイル可能に設計されているため、インタラクティブシェルに必要な便利な速記が不足していますが、非常に具体的で低レベルのデータ/メモリ操作とオペレーティングシステムとの対話を表現するのに適しています。効率的にコンパイルされたコードを書いてみると、これらのことをする自分自身を見つけるでしょう。同時に、bashは他のプログラムを実行し、ファイル/ファイル記述子をリダイレクトし、テキスト文字列を操作するのに非常に巧みであり、インタラクティブシェルで頻繁に実行したいので、これらのプログラムを簡単に短縮できます。
高度な詳細:実際には2つのタイプが混在しているいくつかのプログラミング言語があります(この言語はソースコードを「ほとんど」翻訳してほとんどの解釈/「考え」を一度実行し、わずかな解釈のみを実行します)後で/「考える」見て」)。 Java、Python、および他の多くの最新言語は実際にはハイブリッドです。これらは、解釈された言語の移植性および/または迅速な開発の利点とコンパイルされた言語の速度を提供しようとします。これらの方法を組み合わせる方法はいくつかあり、言語によってこれを異なる方法で行います。このトピックをさらに詳しく調べたい場合は、「バイトコード」でコンパイルするプログラミング言語について読むことができます。そして「JIT」(Just-in-timeコンパイル、プログラムの解釈または実行中にプログラムをコンパイルまたは再コンパイルすることもできます)。
実行可能ビットについて質問しました。実際、実行可能ビットは、オペレーティングシステムにファイルがあることを知らせます。許可する処刑された。私はbashスクリプトがあなたのために動作する唯一の理由がないと思います。実装する権限は実際に bash シェルの内部で実行されるために発生します。通常、オペレーティングシステムは、実行ビットが設定されていないファイルを実行するように要求された場合、単にエラーを返します。しかし、Bashのようないくつかのシェルは、そのエラーをチェックし、基本的にオペレーティングシステムが通常実行するステップ(ファイルの先頭で「#!」行を見つけようとする)を独自にシミュレートしてファイルを解釈するためにプログラム自体を実行しますします
/bin/sh
。 「#!」行がありません。場合によっては、コンパイラがシステムにすでにインストールされており、時にはIDEが独自のコンパイラに付属しているか、コンパイルを実行することがあります。これにより、コンパイルされた言語はコンパイルされていない言語のように「感じられる」ことがありますが、技術的な違いはそのまま残ります。
「コンパイルされた」言語が必ずしも機械語コードにコンパイルされるわけではなく、コンパイル全体が単一のトピックです。デフォルトでは、この用語は非常に広く使用されています。実際にはいくつかのことを示すことができます。特定の意味で、「コンパイラ」は、ある言語(通常は人が使いやすい「高レベル」言語)を別の言語(通常はコンピュータが使いやすい「低レベル」言語)に翻訳する役割を果たします。使用) - 時々頻繁ではありませんが、これは機械語コードです)。また、人々が「コンパイラ」と言うとき、実際には一緒に動作するいくつかのプログラムについて話しています(一般的なCコンパイラの場合、実際には「プリプロセッサ」、コンパイラ自体、「アセンブラ」、および「リンカ」の4つのプログラムです。 )。
答え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.
ご覧のとおり、コンパイラはすべてがリポジトリのどこにあるかを正確に知っているため、「すべてのものを見つける」ステップは必要ありません。
これはそれ自体が1つの手順であり、実行するために「経験豊富な買い物客」を必要としません。必要なのは、「基本的な人間のオペレーティングシステム」を備えた人間だけです。
コンピュータプログラムに戻って:bash
「経験豊富な買い物客」になると、スクリプトをインポートして何もコンパイルせずに直接実行できます。 AC コンパイラは、実行に役立たなくなったスタンドアロンプログラムを生成します。
インタプリタとコンパイラの両方に独自の長所と短所があります。
答え4
英語があなたの母国語ではないと想像してください(英語があなたの母国語でない場合はこれは簡単かもしれません)。
この記事は3つの方法で読むことができます:
- (通訳)読むときに見えるすべての単語を翻訳してください。
- (最適化 - 説明)一般的なフレーズ(例:「あなたの母国語」)を見つけて翻訳して書いてください。次に、すでに翻訳されているフレーズを除いて各単語を翻訳します。
- (編集済み)他の人に全回答を翻訳してもらいます。
コンピュータには、プロセッサが理解する命令とオペレーティングシステム(Windows、Linux、OSXなど)が理解する命令の組み合わせである一種の「母国語」があります。この言語は人が読むことができません。
Bashのようなスクリプト言語は通常、第1および第2のカテゴリに属します。一度に1行ずつ読み、その行を翻訳して実行し、次の行に進みます。Mac と Linux では、Bash、Python、Perl などのさまざまな言語に対して、かなり多くのインタプリタがデフォルトでインストールされます。 Windowsでは直接インストールする必要があります。
多くのスクリプト言語はいくつかの前処理を実行します。それ以外の場合は、アプリケーションの速度を低下させる可能性がある頻繁に実行されるコードブロックをコンパイルして実行を高速化しようとします。あなたが聞いたかもしれないいくつかの用語には、AOT(Ahead-of-Time)またはJIT(Just-In-Time)コンパイルが含まれます。
最後に、コンパイルされた言語(例:C)は、プログラムを実行する前にプログラム全体を翻訳します。これの利点は、翻訳が他のマシンで実行できることです。したがって、プログラムをユーザーに引き渡すときにエラーが発生する可能性がありますが、さまざまな種類のエラーをすでに消去できます。私が言ったように、これを翻訳者に与えれば、garboola mizene resplunks
これはあなたにとって有効な英語のように見えるかもしれませんが、翻訳者は私が話すことができないと言うことができます。コンパイルされたプログラムを実行するときにインタプリタは必要ありません。すでにコンピュータの母国語だからです。
ただし、コンパイルされた言語には欠点があります。コンピュータには、ハードウェアとオペレーティングシステムの機能で構成された母国語があると述べました。さて、Windowsでプログラムをコンパイルすると、コンパイルされたプログラムは次のことを期待しません。 Windows Macで動作します。一部の言語は、ピジン英語と少し似ている中間言語にコンパイルすることでこの問題を解決します。これにより、コンパイルされた言語の利点とわずかな速度の向上が得られますが、これはコードをバンドルする必要があることを意味します。通訳者の使用(または設置された通訳者の使用)。
最後に、IDEがファイルをコンパイルしてコードを実行する前にエラーを通知できます。時々、このエラーチェックは、コンパイラが実行するよりも深いことがあります。コンパイラは通常、合理的なネイティブコードを生成するのに必要な数だけチェックします。 IDE は、多くの場合、いくつかの追加のチェックを実行して、たとえば変数を 2 回定義したか、未使用のアイテムをインポートしたかを知らせることができます。