9

次の「echo」コマンドの実装を見てください。

リストを下に進むにつれて、実装ごとに肥大化が進んでいることに気付くと思います。272行のエコープログラムのポイントは何ですか?

4

3 に答える 3

14

Pike と Kernighan は、記事「UNIX 環境でのプログラムの設計」で、catプログラムが制御引数をどのように付加したかについて説明しています。catその記事ではありませんが、どこかで「旗を振ってバークレーから帰ってきた」というコメントがありました。echoこれは、開発オプションの問題と同様の問題です。(BSD (Mac OS X) の man ページで関連する記事への参照を見つけましたcat。Rob Pike、「UNIX スタイル、または cat -v は有害であると考えられる」、USENIX Summer Conference Proceedings、1983 年。http://quotesも参照してください。 .cat-v.org/programming/ )

Kernighan と Pike は、彼らの著書「The UNIX Programming Environment」の中で、「echo」が引数なしで何をすべきかという主題について、Doug McIlroy を引用しています (1984 年頃)。

哲学に関するもう 1 つの問題はecho、引数が指定されていない場合にどうするかということです。具体的には、空白行を出力するか、何も出力しないかです。私たちが知っている現在のecho実装はすべて空白行を出力しますが、過去のバージョンではそうではなく、この件に関して大きな議論がありました. Doug McIlroy は、このトピックに関する議論の中で、神秘主義の正しい感情を伝えました。

UNIX とエコー

ニュージャージーの土地に住んでいたのは、学者が賞賛するために遠くまで旅した公正なメイドである UNIX でした。彼女の純粋さに目がくらみ、すべての人が彼女を支持しようとしました。ある人は彼女の処女の優雅さ、別の人は洗練された礼儀正しさ、さらに別の人は、はるかに豊かな土地でさえめったに達成されない厳格な仕事を遂行する彼女の機敏さのために. 彼女は非常に心が広く、自然に順応していたので、UNIX は彼女の求婚者の中で最も耐え難いほど裕福な人を除いてすべてを採用しました。すぐに、多くの子孫が成長し、繁栄し、地球の果てまで広がりました。

自然そのものは、他の人間よりも熱心に UNIX に微笑んで答えた。礼儀正しいマナーをほとんど知らなかった謙虚な人々は、彼女の反響を喜んでいました。非常に正確で透き通っているため、荒野への叫び声を混乱させたのと同じ岩や森が彼女に答えることができるとはほとんど信じていませんでした。そして、従順な UNIX は、彼女が求められたことを完璧に反映する義務を負いました。

せっかちなスウェインが UNIX に「何もエコーしない」と尋ねると、UNIX は無理矢理口を開き、何もエコーせず、再び閉じました。

「どういう意味ですか」と若者は尋ねました。今後は、何も反響してはならないときに、決して口を開けてはなりません!」そして、UNIX は義務を負いました。

「だけど私は完璧な演奏がしたいんだ。たとえあなたが何も反響しなくても」と敏感な若者は懇願した。どちらも怒らせたくないので、UNIX はせっかちな若者と鈍感な若者に別のことを言うことに同意しました。彼女は敏感な無を「\n」と呼びました。

しかし今、彼女が「\n」と言ったとき、彼女は本当に何も言わなかったので、口を2回開けなければなりませんでした.1回は「\n」と言い、もう1回は何も言わなかった.\n私には完璧に何もないように聞こえますが、2番目のものはそれを台無しにします. そのうちの 1 つを取り戻してください。そのため、不快感を我慢できなかった UNIX は、いくつかのエコーを元に戻すことに同意し、それを ' \c' と呼びました。敏感な若者は、' \n' と ' \c' を一緒に求めることで、無の完全な反響を聞くことができました。しかし、彼らは、彼が音符を聞く前に、音符の過多で亡くなったと言います。


printfKorn シェルは、C 言語関数に基づいたコマンドを導入 (または、少なくとも組み込み)printf()し、フォーマット文字列を使用してマテリアルの表示方法を制御します。よりも複雑な書式設定に適したツールですecho。しかし、引用で概説されている歴史のために、echoもはや反響するだけではありません。echo に与えられたものを解釈します。

また、コマンドライン引数を解釈echoするには、解釈しない場合よりも多くのコードが必要になることは間違いありません。基本的な echo コマンドは次のとおりです。

#include <stdio.h>
int main(int argc, char **argv)
{
    const char *pad = "";
    while (*++argv)
    {
        fputs(pad, stdout);
        fputs(*argv, stdout);
        pad = " ";
    }
    fputc('\n', stdout);
    return 0;
}

それを達成する他の方法があります。しかし、より複雑なバージョンのechoは、何かを出力する前に引数を精査する必要があり、より多くのコードが必要になります。また、さまざまなシステムがそれぞれの引数のさまざまな量の解釈を行うことを決定したため、さまざまな量のコードが生成されます。

于 2010-07-20T15:28:03.287 に答える
8

肥大化がそれほど大きくないことに気付くでしょう。

  1. コード行のほとんどはコメントです。
  2. コメントではないコード行のほとんどは使用法に関するドキュメントであるため、誰かが「echo --help」を実行すると、何かが実行されます。
  3. 上記以外のコードは、主に echo が取ることができる引数を処理しているように見えます。また、\n や \t などの記号を文字どおりにエコーするのではなく、それらと同等の文字にするための「特別な」展開も処理しているようです。

また、ほとんどの場合、echo コマンドを実行することすらありません。ほとんどの場合、'echo' はシェル ビルトインを呼び出します。少なくとも私のマシンでは、すべての高度な機能/ドキュメントを取得するために入力する必要があります/bin/echo --helpecho --help--help

良い例として、シェルでこれを実行してください。

 echo '\e[31mhello\e[0m'

次に、これを実行します。

 echo -e '\e[31mhello\e[0m'

そして、大きく異なる結果に気付くでしょう。

前者は入力をそのまま出力しますが、後者はhello赤色で出力します。

「hex」コードを使用した別の例:

$echo '\x64\x65\x66'
\x64\x65\x66

$echo -e '\x64\x65\x66'
def

大きく異なる振る舞い。openbsd の実装では、これを行うことはできません =)。

于 2010-07-20T14:01:36.897 に答える
1

最初の実装が気に入るかどうかはわかりません。オプションが 1 つ多すぎます。

-nオプションが必要な場合は、オプションの--処理を停止するオプションも追加すると便利です。そうすれば、ユーザー入力を読み取って出力するシェル スクリプトを作成している場合、ユーザーが-n.

于 2011-02-22T10:11:55.707 に答える