スクリプトを実行する方法はいくつかありますが、私が知っている方法は次のとおりです。
/path/to/script # using the path (absolute or relative)
. script # using the . (dot)
source script # using the `source` command
これ以上ですか?それらの違いは何ですか?あるものを使用する必要があり、別のものを使用する必要がない状況はありますか?
スクリプトを実行する方法はいくつかありますが、私が知っている方法は次のとおりです。
/path/to/script # using the path (absolute or relative)
. script # using the . (dot)
source script # using the `source` command
これ以上ですか?それらの違いは何ですか?あるものを使用する必要があり、別のものを使用する必要がない状況はありますか?
回答:
別の方法は、インタープリターを呼び出してスクリプトへのパスを渡すことです。
/bin/sh /path/to/script
ドットとソースは同等です。(編集:いいえ、そうではありません。KeithBが別の答えのコメントで指摘しているように、「。」はbashに関連するシェルでのみ機能し、「source」はbashおよびcshに関連するシェルの両方で機能します。) -place(スクリプトをコピーして貼り付けたかのように)。これは、スクリプト内のすべての関数と非ローカル変数が残ることを意味します。また、スクリプトがディレクトリへのcdを実行する場合、終了してもそこにいることを意味します。
スクリプトを実行する他の方法では、独自のサブシェルで実行されます。スクリプトの変数は、完了してもまだ生きていません。スクリプトがディレクトリを変更した場合、呼び出し環境には影響しません。
/ path / to / scriptと/ bin / shスクリプトはわずかに異なります。通常、スクリプトの冒頭には次のような「シバン」があります。
#! /bin/bash
これは、スクリプトインタープリターへのパスです。実行時とは異なるインタープリターを指定すると、動作が異なる場合があります(またはまったく機能しない場合があります)。
たとえば、PerlスクリプトとRubyスクリプトは(それぞれ)で始まります:
#! /bin/perl
そして
#! /bin/ruby
を実行してこれらのスクリプトの1つを実行する/bin/sh script
と、それらはまったく機能しません。
Ubuntuは実際にはbashシェルを使用しませんが、dashと呼ばれる非常によく似たシェルを使用します。bashを必要/bin/sh script
とするスクリプトは、dashインタープリターを使用してbashスクリプトを呼び出したばかりなので、実行によって呼び出された場合、わずかに間違って動作する可能性があります。
スクリプトを直接呼び出すことと、スクリプトパスをインタープリターに渡すことのもう1つの小さな違いは、スクリプトを直接実行するために実行可能としてマークする必要がありますが、インタープリターにパスを渡すことによって実行することではありません。
別の小さなバリエーション:スクリプトを実行するこれらの方法のいずれかにevalを付けることができます。
eval sh script
eval script
eval . script
等々。実際には何も変わりませんが、徹底のために含めると思いました。
sh
対応しdash
ていbash
ますが、ではありません。
ほとんどの人は、次のデバッグフラグをスクリプトに追加して、シェルスクリプトをデバッグします。
set -x # Print command traces before executing command.
set -v # Prints shell input lines as they are read.
set -xv # Or do both
ただし、これは、エディターでファイルを開き(ファイルを編集する権限がある場合)、のような行を追加しset -x
てファイルを保存し、ファイルを実行する必要があることを意味します。その後、同じ手順を実行しset -x
、などを削除する必要があります。これは面倒な場合があります。
すべてを行う代わりに、コマンドラインでデバッグフラグを設定できます。
$ bash -x ~/bin/ducks
+ du -cks -x dir1 dir2 dir3 file1 file2 file3
+ sort -n
+ tail .ducks
123 etc
424 bin
796 total
$ sh -xv ~/bin/ducks
#!/usr/bin/env bash
# Find the disk hog
# Borrowed from http://oreilly.com/pub/h/15
...
...
emulate sh 2>/dev/null
シェルスクリプトの一番上に置く習慣になりました。zshで実行すると、これによりPOSIX互換モードになります。他のシェルで実行した場合、この行は効果がありません。次に、でスクリプトを実行できますzsh -x /path/to/script
。ここでzshが好きなのは、bashやkshよりも良いトレースを提供するからです。
ショーンJ.ゴフは多くの良い点を挙げましたが、ストーリー全体は含まれていませんでした。
Ubuntuは実際にはbashシェルを使用しませんが、dashと呼ばれる非常によく似たシェルを使用します。
/bin/sh
ダッシュインタープリタを使用してbashスクリプトを呼び出しただけなので、bashを必要とするスクリプトは、スクリプトを実行して呼び出されたときにわずかに間違って動作する可能性があります。
多くのシステムスクリプト(init.dや/ etcなど)にはシバン#!/bin/sh
があります/bin/sh
が、実際には別のシェルへのシンボリックリンクです(以前/bin/bash
は最近)/bin/dash
。しかし、それらの1つがとして呼び出される/bin/sh
と、動作が異なります。つまり、POSIX互換モードに固執します。
彼らはどうやってこれをしますか?さて、彼らはどのように呼び出されたかを検査します。
シェルスクリプト自体は、それがどのように呼び出されたかをテストし、それに応じて異なることを実行できますか?はい、できます。したがって、それを呼び出す方法は常に異なる結果につながる可能性がありますが、もちろんあなたを困らせることはほとんどありません。:)
経験則として:bashのような特定のシェルを学習していて、bashチュートリアルからコマンドを作成する場合は、特に明記されている場合を除き#!/bin/bash
、ではなく見出しを付けてください#!/bin/sh
。そうしないと、コマンドが失敗する可能性があります。スクリプトを自分で書かれていない場合や、(それを直接呼び出して./foo.sh
、bar/foo.sh
()の代わりに、シェルを推測しsh foo.sh
、sh bar/foo.sh
)。シバンは正しいシェルを呼び出す必要があります。
そして、他の2種類の呼び出しがあります。
cat foo.sh | dash
dash < foo.sh
sh script
bash script
もっとあるかどうか考えています...
.
とsource
同じです。実行後、環境の変更はscript
保持されます。通常、Bashライブラリのソースとして使用されるため、ライブラリはさまざまなスクリプトで再利用できます。
また、現在のディレクトリを保持する良い方法です。スクリプトでディレクトリを変更すると、そのスクリプトを実行するシェルには適用されません。ただし、実行するためにソースを指定すると、スクリプトの終了後、現在のディレクトリが保持されます。
.
sh / bashおよび関連するシェルでのみ機能します。 source
cshおよび関連するシェルでも機能します。
「userland exec」は別の方法としてカウントされますか?Userland execはコードをロードし、execve()システムコールを使用せずにコードを実行します。