「if」と「then」は実際にプログラムされていますか


15

私はセミコロンがプログラムを分離するために使用されることを読みました:

$ echo 3; ls -la

それはを意味するのですかifthenそしてelseここには別のプログラムがありますか?

$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi

この質問はセミコロンに関するものではありません。



1
@StephenRauch実際には重複していません。さらに理解を深めるための試みとして、それはそのQからの合理的な結果です。
ジプシースペルウィーバー

より多くのプログラムの定式化:[ $variable == abcdef ] && echo yes || echo no
ハーゲン・フォン・

2
@HagenvonEitzenは厳密には同等ではありません。最初のブランチ内のステートメントが失敗すると、2番目のブランチも実行されます。
モルゲン

回答:


26

;セパレート文(緩く話します)。交換し、常に(ほぼ)可能である;改行で。

;したがってif、2つのプログラムを分離し、then「プログラム」である必要があると言うのは、予約語、シェル関数、組み込みユーティリティと外部ユーティリティ、およびパイプとブール演算子などを使用したこれらの組み合わせでステートメントを作成できるため、少し単純すぎますなど

両方ifthenの単語に予約されているシェルの文法ではなく、「プログラム」。ここで、それらは技術的に複合コマンドと呼ばれるものを構築するために使用されます。

echoシェルの組み込みユーティリティである可能性が高く(そうである必要はありません)、lsおそらく外部ユーティリティ(または言う「プログラム」)です。


7

シェルの使用の非常に基本的なことを学習し始めたとき、それはかなり最初の近似ですが、「プログラムの実行方法は次のとおりです」および「複数のプログラムを1行で次々と実行する方法は次のとおりです」 、実際にはそうではありません。

初心者にとっては理解しにくいが、より正確な説明は、シェル言語がコンピューター言語であるということです。構文があります。この構文は、(特に)改行、演算子、単語、予約語などのさまざまな語彙要素で構成されます。

ifthenelse、およびfiすべてのある予約語。それらは、文法に従って、シェルに与える入力を解析するときに特定の意味を持ちます。同様に、セパレータ演算子です。;

したがって、シェル言語での入力は、全体として、別のプログラム、インタープリター、シェルによって解釈されるコンピュータープログラムです。個々の文法部分はプログラムではありません。シェル言語は、実行するシェルの(他の)プログラムを指定する方法です。

[は、演算子などのシェル文法の特別な語彙要素ではありません。それは普通の言葉で、そのようなプログラムの名前を1つ付け[ます。多くのシェルには、シェルプログラム自体のコードに組み込まれたこのプログラムの組み込みバージョンがありますが、シェル以外のプログラムが呼び出すことができるまたはなど、この名前の外部プログラムを見つけることもできます。同様に、特殊なシェルの字句要素でもありません。それは普通の言葉で、プログラムの議論になります。プログラムは、その最後の引数は、それが実行されたときに、であることが必要で、それが次に無視する進み、。/bin/[/usr/bin/[][[]

あなたの質問で名前が付けられた別の同様のプログラムはechoです。繰り返しますが、ほとんどのシェルにはこのプログラムの組み込みバージョンがあります。しかし、再びどこかのような、また、プログラムの外部のバージョンが存在する/bin/echo/usr/bin/echo、プログラムのために他よりもシェルを呼び出すために。

質問で名前が付けられている3番目のプログラムはlsです。通常、シェルにはこのプログラムの組み込みバージョンはありません。これは外部プログラムであり、/bin/lsor などのどこかにあり/usr/bin/lsます。

Bourne Againシェルについては、GNU Bourne Againシェル情報ドキュメントの基本的なシェル機能でこれについて詳しく読むことができます。他のシェルには、当然、異なる文法があります。シングルUnixの仕様は、(彼らのPOSIX準拠モードで)すべてのPOSIX準拠のシェルはに付着することになっているという構文について説明します。

参考文献

  • シェル文法」。 シェルコマンド言語。基本仕様の問題7.オープングループ。IEEE 1003.1-2008。ISBN 1937218812。
  • testユーティリティ。基本仕様の問題7.オープングループ。IEEE 1003.1-2008。ISBN 1937218812。
  • シェル文法」。 Zシェルマニュアル。バージョン5.3.1。2017年。

5

ifthenおよびelse外部プログラムとして考えるのは、実際にはそれほどフェッチされません。実際には、トンプソンシェルは、元の第1版ではUnixの実装ifgoto外部のプログラムなど。これは、サブプロセスがシェルプロセスとファイル記述子を共有しているため可能です。したがって、(forward)gotoはターゲットラベルを見つけて終了するまで入力を読み取るだけでした。Thompson shellを参照してください。


または、実際にLaurent Bercot's ifおよびを参照してください。ifelseこれらはの一部ですexeclineifただし、これらは問題に含まれていません。
JdeBP

2
「それは場合を考えると、実際にこじつけではありません、そして、外部のプログラムなどの他に、」彼らがいないだからまあ、それは、あります。
モニカとの軽さレース

2

thenそしてelseプログラムではありません。他の部分は。;それらの直後には' がありませんが、コマンドの後にはそれらが先行することに注意してください。

[ ... ] 、コマンド、および必要と;別のコマンドの開始が続いた場合。

AFAIK、Bashのすべての制御構造、およびおそらくほとんどの* nixシェルは同じです。通訳者への指示です。一方、テストまたは条件は、「実行」されたコマンドであるプログラム/プロセスを使用します。コマンドにthenつながる行の一部であるためecho、前のコマンドと改行で区切る必要があります[ ... ]。制御するコマンドであるから分離する必要はありませんecho yes

法的には、見苦しくて読みにくいですが、これもできます。

if [ $VARIABLE == abcdef ]
then echo yes
else echo no
fi

;ここでは、コントロールが独自の行にない場合でも、コントロール間に何も必要がないことに注意してください。

興味深いことに、制御構造全体(if ... fi)はシェルコマンドであり、全体は改行またはで終わる必要があります;。最後の行はできませんがfi echo done、する必要がありますfi; echo done。割り当てVARIABLE='abcdef'と同じはコマンドです。

制御構造全体はコマンドですが、プログラムではありません。


1

ifelifthen、およびfi構築物のいずれかを実施するために使用されるすべての予約キーワードは、シェルにおけるそれらの名前のいずれかによって、コマンド(またはむしろ、別のコマンド)が存在しないことを意味しており、シェル中の化合物のコマンドと呼ばれます。;一般的な目的は、コマンドを分離することではなく、コマンドリストを終了することです。たとえば、次は有効なifステートメントです。

if echo foo; echo bar; echo baz; then echo done; echo really done; fi

ifステートメントの条件はコマンドリストecho foo; echo bar; echo bazです。パーサーはthen、セミコロンのすぐ後に続くが予約キーワードであるためコマンドになれないため、条件が終了したことを認識しています。したがって、それに続くの thenは身体の始まりであることを知っています。同様にfi、予約キーワードであるため、ifステートメントの本文の3番目のコマンドにすることはできませんが、複合コマンドの終了を示します。


おかげで、これが使用されている場合if program1 foo; program2 bar; program3 baz; 、どのプログラムステータスがである必要が0ありますので、シェルはthen?最後の?
マキシムKoretskyi

ただprogram3 baz。コマンドのリストの終了ステータスは、そのリストの最後のコマンドの終了ステータスです。他の2つは、状態に影響を与えずに失敗する可能性があります。
chepner
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.