
シェルスクリプトは、Unixシェル(コマンドラインインタープリタ)で実行されるように設計されたコンピュータプログラムです。[ 1 ]シェルスクリプトのさまざまな方言は、コマンド言語 とみなされます。シェルスクリプトによって実行される典型的な操作には、ファイル操作、プログラムの実行、テキストの出力などがあります。環境を設定し、プログラムを実行し、必要なクリーンアップやログ記録を行うスクリプトは、ラッパーと呼ばれます。
この用語は、オペレーティングシステムのシェルを自動的に実行するモードを意味する場合にもより一般的に使用されます。異なるオペレーティングシステムはそれぞれ、これらの機能に固有の名前を使用します。すべてのUnixライクなシステムには、少なくとも1つのPOSIXシェルが含まれており、通常はbashまたはzsh互換モードのいずれかです。[ 2 ]
シェバン(またはハッシュバン)は、システムがファイルを実行するために使用するインタプリタを決定するために使用する特殊なコメントです。シェバンはファイルの最初の行でなければならず、「#!」で始まる必要があります。[ 3 ] Unix ライクなオペレーティングシステムでは、「 」のプレフィックスに続く文字は、#!スクリプトを解釈する実行可能プログラムへのパスとして解釈されます。[ 4 ]
シェルスクリプトは、特別な環境設定、コマンドオプション、または後処理が自動的に適用されるシステムコマンドの便利なバリエーションを提供するが、新しいスクリプトは依然として完全に通常のUnixコマンドとして機能できるようにする。
例えば、ファイル一覧を表示するコマンドであるlslのバージョンを作成し、より短いコマンド名 を付け、通常はユーザーのbinディレクトリに として保存し、デフォルトのコマンドオプションをあらかじめ用意しておくことが考えられます。/home/username/bin/l
#!/bin/sh LC_COLLATE = C ls -FCas " $@ "ここでは、最初の行でシェバンを使用して、スクリプトの残りの部分を実行するインタープリタを指定します。2 行目では、ファイル形式インジケータ、列、すべてのファイル (省略なし)、ブロック単位のサイズなどのオプションを使用してリストを作成します。LC_COLLATE=Cデフォルトの照合順序は、大文字と小文字を一緒に折り畳まない、名前の句読点を無視する副作用としてドットファイル-aと通常のファイル名を混在させない (ドットファイルは通常、のようなオプションが使用された場合にのみ表示されます) ように設定され、に"$@"渡されたすべてのパラメータがlls のパラメータとして渡されるため、ls が認識するすべての通常のオプションやその他の構文を引き続き使用できます。
ユーザーは、l最もよく使用される短縮リストを簡単に使用できます。
ショートカットとして使用できるシェルスクリプトの別の例としては、指定されたディレクトリ内のすべてのファイルとディレクトリのリストを表示するスクリプトが挙げられます。
#!/bin/sh クリア ls -al この場合、シェルスクリプトは通常の開始行である#!/bin/shで始まります。続いて、スクリプトはclearコマンドを実行し、次の行に進む前にターミナル上のすべてのテキストをクリアします。次の行は、スクリプトのメイン機能を提供します。ls -alコマンドは、スクリプトが実行されているディレクトリにあるファイルとディレクトリを一覧表示します。lsコマンドの属性は、ユーザーのニーズに合わせて変更できます。
シェルスクリプトを使用すると、コマンドラインインターフェースで手動で入力する複数のコマンドを自動的に実行でき、ユーザーが各段階をトリガーするのを待つ必要がなくなります。たとえば、3つのCソースコードファイルがあるディレクトリで、それらから最終プログラムをビルドするために必要な4つのコマンドを手動で実行する代わりに、POSIX準拠のシェル用のスクリプトを作成し、そのスクリプトをファイルbuildと同じディレクトリに保存して、それらを自動的にコンパイルすることができます。
#!/bin/sh printf 'コンパイル中...\n' cc -c foo.c cc -c bar.c cc -c qux.c cc -o myprog foo.o bar.o qux.o printf '完了しました。\n'このスクリプトを使えば、編集中のファイルを保存し、エディタを一時停止して、./build更新されたプログラムを作成し、テストしてからエディタに戻るという一連の操作を行うことができる。しかし、1980年代頃から、このようなスクリプトは、プログラムの作成に特化したmakeのようなユーティリティに取って代わられるようになった。
単純なバッチジョブは独立したタスクには珍しくありませんが、シェルループ、テスト、変数を使用すると、ユーザーにはるかに高い柔軟性が提供されます。このファイルを使用すると、JPEG画像をPNG画像に変換するPOSIX shスクリプトを作成できます。このスクリプトでは、画像名はスクリプト内でそれぞれリストされるのではなく、コマンドラインで(ワイルドカードを使用して)指定されます。通常、このスクリプトは次のようなファイルに保存されます。/home/username/bin/jpg2png
#!/bin/sh for jpg ; do # 指定された各ファイル名の代わりに $jpg を順番に使用しますpng = ${ jpg %.jpg } .png # ファイル名の .jpg を .png に置き換えて PNG バージョンを作成しますprintf 'converting "%s" ...\n' " $jpg " # スクリプトを実行しているユーザーにステータス情報を出力しますif convert " $jpg " jpg.to.png ; then # convert (ImageMagick によって提供される) を使用して、一時ファイルに PNG を作成しますmv jpg.to.png " $png " # うまくいった場合は、一時的な PNG イメージの名前を正しい名前に変更しますelse # ...そうでない場合は、エラーを報告してスクリプトを終了しますprintf > & 2 'jpg2png: エラー: 失敗した出力が "jpg.to.png" に保存されました。\n' exit 1 fi # "if" テスト構造の終了done # "for" ループの終了printf 'すべての変換が成功しました\n' # ユーザーに良い知らせを伝えますこのjpg2pngコマンドは、JPEG画像が入ったディレクトリ全体に対して、以下のコマンドで実行できます。/home/username/bin/jpg2png *.jpg
現代のシェルの多くは、制御フロー構造、変数、コメント、配列、サブルーチンなど、より高度な汎用プログラミング言語にしか見られない様々な機能を提供しています。こうした機能が利用できるため、シェルスクリプトとしてかなり高度なアプリケーションを作成することが可能です。しかしながら、ほとんどのシェル言語はデータ型システム、クラス、スレッド処理、複雑な数学演算、その他の一般的な言語機能のサポートがほとんど、あるいは全くないため、依然として制約があります。また、一般的に、コンパイルされたコードや、速度を重視して書かれたインタプリタ型言語よりも処理速度がはるかに遅いという問題もあります。
標準のUnixツールであるsedとawkは、シェルプログラミングのための追加機能を提供します。PerlもTclなどの他のスクリプト言語と同様に、シェルスクリプトに埋め込むことができます。[ 5 ] PerlとTclにはグラフィックツールキットも付属しています。
UNIX、Linux、およびPOSIX準拠のオペレーティングシステムによく見られるスクリプト言語には、以下のようなものがあります。
sh)は、AT&Tの著作権保護下にあるため、現在では一般的に使用されていません。ash)、ボーン貝の変種、AT&Tの著作権保護下dash) は、ash のオープンソース複製であり、「西側で最速のシェル」です。[ 6 ] [ 7 ]bash)、Bourne Shell のオープンソース複製で、現在はより多くの機能を備えています[ 8 ]BusyBox Dynamic Interface)、Debian 1.3 以前の古いバージョンの BASH、Slackware、およびいくつかの Void。[ 9 ]fish)、メンテナーはPOSIXを維持することを誓ってはいないが、POSIXの構文が直感的でない場合、FISHはBASHに準拠し、BASH主義に従う。 [ 10 ]一般的に使用されている非POSIXシェルには以下のようなものがあります。
zsh)nu)xonsh)、「コンチ」と発音される、Pythonベースのシェルpwsh)C シェルと Tcl シェルは、同名のプログラミング言語と構文が非常によく似ており、Korn シェルと Bash は、ALGOL言語をベースに他の言語の要素も加えた Bourne シェルの発展形です。[ 11 ]一方、さまざまなシェルとawk、sed、grepなどのツール、BASIC、Lisp、CなどはPerlプログラミング言語に貢献しました。[ 12 ]
かつて人気だった貝殻には以下のようなものがある。
osh)、これは「第6版UNIXの標準コマンドインタープリタの移植版」[ 13 ]です。kshにほぼ置き換えられた。tcsh)およびその前身であるC shell(csh)Python、Ruby、C、Java、Perl、Pascal、Rexxなどをベースにしたシェルなどの関連プログラムも、様々な形式で広く利用可能です。
いわゆるリモートシェルなど
これらは実際には、リモートシステム上でより複雑なシェルを実行するためのツールに過ぎず、それ自体には「シェル」のような特性はありません。
Rexx、Python、Perl、Tclなどの強力なスクリプト言語は、従来のシェルスクリプトでは快適に処理できないほど大規模、複雑、または反復的なタスクに対処するために導入され、CやJavaのようなコンパイル言語に伴うオーバーヘッドを回避しています。[ 14 ]
スクリプト言語と汎用高水準プログラミング言語の区別はしばしば議論されるが、スクリプト言語は一般的に、解釈型の性質、簡略化された構文、タスクの自動化、システム操作の調整、コンポーネント間の「グルーコード」の記述を主な用途としている。[ 15 ] Python、Rexx、JavaScriptなどのスクリプト言語がバイトコードへのコンパイルをサポートしたり、JITを使用してパフォーマンスを向上させたりしている場合でも、スタンドアロンのアプリケーション開発ではなく、自動化、軽量ツール、スクリプト環境との歴史的な関連性から、依然として一般的に「スクリプト言語」と呼ばれている。
スクリプト作成はプログラミングの一形態である。「スクリプト作成」は軽量でタスク指向の自動化を強調する傾向があるが、より広い意味での「プログラミング」は、コンパイル言語や構造化言語によるスクリプト作成とソフトウェア開発の両方を含む。したがって、スクリプト作成は、コンピュータに特定のタスクを実行するように指示するコードを記述することであり、プログラミングの基本的な定義を満たしている。[ 16 ]
シェルスクリプトはソフトウェア開発の初期段階でよく用いられ、後々、Perl、Python、Cなど、異なる基盤となる実装に変換されることがよくあります。インタープリタディレクティブを使用することで、実装の詳細をファイル名の拡張子として公開するのではなく、スクリプト内部に完全に隠蔽することができ、エンドユーザーに影響を与えることなく、異なる言語でのシームレスな再実装が可能になります。
「.sh」ファイル拡張子を持つファイルは通常何らかのシェルスクリプトですが、ほとんどのシェルスクリプトにはファイル名拡張子がありません。[ 17 ] [ 18 ] [ 19 ] [ 20 ]
シェルスクリプトを作成する最大の利点の1つは、コマンドと構文がコマンドラインで直接入力するものとまったく同じであることです。スクリプトが別の言語で書かれている場合や、コンパイル言語が使用されている場合とは異なり、プログラマは全く異なる構文に切り替える必要がありません。
シェルスクリプトは、他のプログラミング言語で同等のコードを書くよりもはるかに速く書ける場合が多い。その利点は数多くあり、プログラムやファイルの選択が容易で、すぐに実行を開始でき、対話型のデバッグが可能だ。シェルスクリプトは、既存のプログラムにシーケンス処理や意思決定の連携機能を持たせるために使用でき、中規模のスクリプトであればコンパイル手順が不要という利点もある。インタプリタ方式で実行できるため、デバッグコードをスクリプトに簡単に記述して再実行し、バグを検出して修正できる。専門知識のないユーザーでもスクリプトを使ってプログラムの動作をカスタマイズでき、シェルスクリプトは限定的ではあるがマルチプロセッシングにも対応できる。
一方、シェルスクリプトは、コストのかかるエラーが発生しやすい。rm -rf * /意図せず入力ミスをしてしまうこと(本来は と入力すべきところを とrm -rf */入力してしまうこと)は、Unix コミュニティではよく知られている。余分なスペースが 1 つあるだけで、現在のディレクトリに含まれるすべてのサブディレクトリを削除するコマンドが、ファイルシステムのルートディレクトリからすべてを削除するコマンドに変わってしまう。[ 21 ]同様の問題でcpや がmv危険な武器に変わってしまう可能性があり、>リダイレクトを誤用するとファイルの内容が削除されてしまう可能性がある。[ 22 ]
もう一つの大きな欠点は、実行速度が遅いことと、ほぼすべてのシェルコマンドを実行するたびに新しいプロセスを起動する必要があることです。効率的なフィルタコマンドが処理の大部分を実行するパイプラインを構築することでスクリプトのタスクを完了できる場合は、速度低下は軽減されますが、複雑なスクリプトは通常、同等のタスクを実行する従来のコンパイル済みプログラムよりも数桁遅くなります。
異なるプラットフォーム間には互換性の問題もあります。Perlの生みの親であるラリー・ウォールは、「シェルスクリプトよりもシェルを移植する方が簡単だ」と有名な言葉を残しています。[ 23 ]
同様に、より複雑なスクリプトはシェルスクリプト言語自体の制限に直面する可能性があり、その制限によって質の高いコードを書くことが難しくなり、元のシェル言語の問題を改善するためのさまざまなシェルによる拡張機能が問題を悪化させる可能性があります。[ 24 ]
Many disadvantages of using some script languages are caused by design flaws within the language syntax or implementation, and are not necessarily imposed by the use of a text-based command-line; there are a number of shells which use other shell programming languages or even full-fledged languages like Scsh (which uses Scheme).
Many scripting languages share similar syntax and features due to their adherence to the POSIX standard, and several shells provide modes to emulate or maintain compatibility with others. This allows scripts written for one shell to often run in another with minimal changes.
For example, Bash supports much of the original Bourne shell syntax and offers a POSIX-compliant mode to improve portability. However, Bash also includes a number of extensions not found in POSIX, commonly referred to as bashisms. While these features enhance scripting capabilities, they may reduce compatibility with other shells like Dash or ksh.
Interoperability software such as Cygwin, the MKS Toolkit, Interix (formerly part of Microsoft Windows Services for UNIX), Hamilton C shell, and UWIN (AT&T Unix for Windows) enables Unix shell programs to run on Windows NT-based systems, though some features may not be fully supported on the older MS-DOS/Windows 95 platforms. Earlier versions of the MKS Toolkit also provided support for OS/2.
スクリプト言語は、定義上、拡張可能です。Unix やその他のPOSIX準拠システムでは、awkやsed を使用して、シェルスクリプトの文字列および数値処理機能を拡張します。Tcl 、 Perl、Rexx、Python にはグラフィックツールキットがあり、シェルスクリプトの速度ボトルネックとなる関数やプロシージャをコーディングしたり (C、Fortran、アセンブリ言語などははるかに高速です)、ソケットやその他の接続機能、高度なテキスト処理、呼び出し元のスクリプトにこれらの機能がない場合の数値処理、自己記述および自己修正コード、再帰、直接メモリアクセス、さまざまな種類のソートなどの手法など、シェル言語では利用できない機能を追加したりするために使用できます。これらの機能は、メインスクリプトでは困難または不可能です。Visual Basic for ApplicationsおよびVBScript を使用すると、スプレッドシート、データベース、あらゆる種類のスクリプト可能なプログラム、通信ソフトウェア、開発ツール、グラフィックツール、コンポーネントオブジェクトモデルを介してアクセスできるその他のソフトウェアなどを制御および通信できます。
変数、ループ、条件分岐などを備えています。
実際にはスクリプト作成にも優れた汎用プログラミング言語です。実際、スクリプト作成はプログラミング全般のごく一部に過ぎません。
シェルスクリプトにファイル拡張子を使用する代わりに、拡張子のないファイル名を保持し、インタープリタがshebang(#!)を調べてタイプを識別するようにすることが推奨されます。
シェルスクリプトには特別なファイル拡張子は必要ないので、拡張子は空白のままにしてください(または、必要に応じて拡張子.shを追加することもできますが、これは必須ではありません)。