web-dev-qa-db-ja.com

スクリプトがソースされているかどうかを検出する方法

ソースがある場合、exitを呼び出さないスクリプトがあります。

$0 == bashしかし、スクリプトが別のスクリプトからソースされている場合、またはユーザーがkshなどの別のシェルからソースしている場合、これには問題があります。

スクリプトがソースされているかどうかを検出する信頼できる方法はありますか?

175
brianegge

これは、BashとKornの間で移植可能であるようです:

[[ $_ != $0 ]] && echo "Script is being sourced" || echo "Script is a subshell"

これに似た行またはpathname="$_"(後のテストとアクションを含む)のような割り当ては、スクリプトの最初の行またはShebangの後の行(使用する場合は、kshの順序である必要があります)ほとんどの状況で機能するように)。

58

BashバージョンがBASH_SOURCE配列変数について知っている場合は、次のようなものを試してください。

# man bash | less -p BASH_SOURCE
#[[ ${BASH_VERSINFO[0]} -le 2 ]] && echo 'No BASH_SOURCE array variable' && exit 1

[[ "${BASH_SOURCE[0]}" != "${0}" ]] && echo "script ${BASH_SOURCE[0]} is being sourced ..."
146
barroyo

@DennisWilliamsonの回答を読んだ後、いくつかの問題があります。以下を参照してください。

この質問は kshandbash を表しているため、この答えには別の部分があります- ksh ...以下を参照してください。

シンプル bash way

[ "$0" = "$BASH_SOURCE" ]

試してみましょう(そのbashが可能だから、その場で:-):

source <(echo $'#!/bin/bash
           [ "$0" = "$BASH_SOURCE" ] && v=own || v=sourced;
           echo "process $$ is $v ($0, $BASH_SOURCE)" ')
process 29301 is sourced (bash, /dev/fd/63)

bash <(echo $'#!/bin/bash
           [ "$0" = "$BASH_SOURCE" ] && v=own || v=sourced;
           echo "process $$ is $v ($0, $BASH_SOURCE)" ')
process 16229 is own (/dev/fd/63, /dev/fd/63)

.の代わりにsourceを使用して読みやすくします(.sourceのエイリアスです):

. <(echo $'#!/bin/bash
           [ "$0" = "$BASH_SOURCE" ] && v=own || v=sourced;
           echo "process $$ is $v ($0, $BASH_SOURCE)" ')
process 29301 is sourced (bash, /dev/fd/63)

プロセスがsourcedのままである間、プロセス番号は変更されないことに注意してください。

echo $$
29301

$_ == $0比較を使用しない理由

多くのケースを確保するために、trueスクリプトの作成を開始します。

#!/bin/bash

# As $_ could be used only once, uncomment one of two following lines

#printf '_="%s", 0="%s" and BASH_SOURCE="%s"\n' "$_" "$0" "$BASH_SOURCE"
[[ "$_" != "$0" ]] && DW_PURPOSE=sourced || DW_PURPOSE=subshell

[ "$0" = "$BASH_SOURCE" ] && BASH_KIND_ENV=own || BASH_KIND_ENV=sourced;
echo "proc: $$[ppid:$PPID] is $BASH_KIND_ENV (DW purpose: $DW_PURPOSE)"

これをtestscriptというファイルにコピーします:

cat >testscript   
chmod +x testscript

これでテストできます:

./testscript 
proc: 25758[ppid:24890] is own (DW purpose: subshell)

それで大丈夫です。

. ./testscript 
proc: 24890[ppid:24885] is sourced (DW purpose: sourced)

source ./testscript 
proc: 24890[ppid:24885] is sourced (DW purpose: sourced)

それで大丈夫です。

ただし、-xフラグを追加する前にスクリプトをテストするには:

bash ./testscript 
proc: 25776[ppid:24890] is own (DW purpose: sourced)

または、事前定義された変数を使用するには:

env PATH=/tmp/bintemp:$PATH ./testscript 
proc: 25948[ppid:24890] is own (DW purpose: sourced)

env SOMETHING=PREDEFINED ./testscript 
proc: 25972[ppid:24890] is own (DW purpose: sourced)

これはもう機能しません。

コメントを5行目から6行目に移動すると、より読みやすい回答が得られます。

./testscript 
_="./testscript", 0="./testscript" and BASH_SOURCE="./testscript"
proc: 26256[ppid:24890] is own

. testscript 
_="_filedir", 0="bash" and BASH_SOURCE="testscript"
proc: 24890[ppid:24885] is sourced

source testscript 
_="_filedir", 0="bash" and BASH_SOURCE="testscript"
proc: 24890[ppid:24885] is sourced

bash testscript 
_="/bin/bash", 0="testscript" and BASH_SOURCE="testscript"
proc: 26317[ppid:24890] is own

env FILE=/dev/null ./testscript 
_="/usr/bin/env", 0="./testscript" and BASH_SOURCE="./testscript"
proc: 26336[ppid:24890] is own

難しい: ksh now ...

ksh をあまり使用しないので、manページを読んだ後、私の試みがあります:

#!/bin/ksh

set >/tmp/ksh-$$.log

これをtestfile.kshにコピーします:

cat >testfile.ksh
chmod +x testfile.ksh

2回実行するより:

./testfile.ksh
. ./testfile.ksh

ls -l /tmp/ksh-*.log
-rw-r--r-- 1 user user   2183 avr 11 13:48 /tmp/ksh-9725.log
-rw-r--r-- 1 user user   2140 avr 11 13:48 /tmp/ksh-9781.log

echo $$
9725

および参照:

diff /tmp/ksh-{9725,9781}.log | grep ^\> # OWN SUBSHELL:
> HISTCMD=0
> PPID=9725
> RANDOM=1626
> SECONDS=0.001
>   lineno=0
> SHLVL=3

diff /tmp/ksh-{9725,9781}.log | grep ^\< # SOURCED:
< COLUMNS=152
< HISTCMD=117
< LINES=47
< PPID=9163
< PS1='$ '
< RANDOM=29667
< SECONDS=23.652
<   level=1
<   lineno=1
< SHLVL=2

sourced実行で継承された変数がいくつかありますが、実際には何も関係ありません...

$SECONDS0.000に近いことを確認することもできますが、それは手動で調達されたケースのみを保証します...

what's親が何であるかを確認することさえできます:

これをtestfile.kshに配置します:

ps $PPID

より:

./testfile.ksh
  PID TTY      STAT   TIME COMMAND
32320 pts/4    Ss     0:00 -ksh

. ./testfile.ksh
  PID TTY      STAT   TIME COMMAND
32319 ?        S      0:00 sshd: user@pts/4

またはps ho cmd $PPIDですが、これは1レベルのサブセッションでのみ機能します...

申し訳ありませんが、 ksh の下で、信頼できる方法を見つけることができませんでした。

67
F. Hauri

_BASH_SOURCE[]_の回答(bash-3.0以降)は最も簡単に見えますが、_BASH_SOURCE[]_は関数本体の外で動作するようにドキュメント化されていません(現在動作している、manページと一致しない)。

Wirawan Purwantoが提案した最も堅牢な方法は、関数内で_FUNCNAME[1]_をチェックすることです

_function mycheck() { declare -p FUNCNAME; }
mycheck
_

次に:

_$ bash sourcetest.sh
declare -a FUNCNAME='([0]="mycheck" [1]="main")'
$ . sourcetest.sh
declare -a FUNCNAME='([0]="mycheck" [1]="source")'
_

これは、callerの出力をチェックするのと同じです。値mainsourceは、呼び出し元のコンテキストを区別します。 _FUNCNAME[]_を使用すると、caller出力のキャプチャと解析を節約できます。ただし、ローカルコール深度を正確に把握または計算する必要があります。別の関数またはスクリプト内からソースされるスクリプトのようなケースでは、配列(スタック)が深くなります。 (FUNCNAMEは特別なbash配列変数です。unsetでない限り、呼び出しスタックに対応する連続したインデックスが必要です。)

_function issourced() {
    [[ ${FUNCNAME[@]: -1} == "source" ]]
}
_

(bash-4.2以降では、配列の最後の項目に対して、より単純な形式_${FUNCNAME[-1]}_を使用できます。以下のDennis Williamsonのコメントのおかげで改善および簡素化されました。)

しかし、述べられているあなたの問題は、「私は、それが調達されている場合、「終了」を呼び出したくないスクリプトを持っています)。この状況の一般的なbashイディオムは次のとおりです。

_return 2>/dev/null || exit
_

スクリプトがソースされている場合、returnはソースされたスクリプトを終了し、呼び出し元に戻ります。

スクリプトが実行されている場合、returnはエラーを返し(リダイレクトされます)、exitは通常どおりスクリプトを終了します。 returnexitの両方が、必要に応じて終了コードを取ることができます。

悲しいことに、これはkshで動作しません(少なくともここにあるAT&T派生バージョンでは動作しません)。関数の外部で呼び出された場合、returnexitと同等として扱われますまたはドットソースのスクリプト。

Updatedkshの現代バージョンであなたがcanすることは、関数呼び出しの深さに設定される特殊変数_.sh.level_。呼び出されたスクリプトの場合、これは最初に設定解除され、ドットソースのスクリプトの場合は1に設定されます。

_function issourced {
    [[ ${.sh.level} -eq 2 ]]
}

issourced && echo this script is sourced
_

これは、bashバージョンほど堅牢ではありません。テストするファイルのissourced()を最上位または既知の関数の深さで呼び出す必要があります。

kshディシプリン関数とデバッグトラップトリックを使用してbash FUNCNAME配列をエミュレートするgithubの このコード にも興味があるかもしれません。)

ここでの正解: http://mywiki.wooledge.org/BashFAQ/109 は、シェル状態の別の指標(ただし不完全)として_$-_も提供します。


ノート:

  • 「main」および「source」という名前のbash関数を作成することができます( 組み込みをオーバーライド )、これらの名前は_FUNCNAME[]_に表示されますが、その配列の最後の項目のみがあいまいさはありませんでした。
  • pdkshに対する良い答えがありません。私が見つけることができる最も近いものはpdkshにのみ適用され、スクリプトの各ソースは新しいファイル記述子を開きます(元のスクリプトでは10から始まります)。ほぼ確実にあなたが頼りにしたいものではない...
30
mr.spuratic

編集者注:この回答のソリューションは堅牢に機能しますが、bashのみです。合理化することができます
_(return 2>/dev/null)_。

TL; DR

returnステートメントを実行してみてください。スクリプトがソースされていない場合、エラーが発生します。そのエラーをキャッチして、必要に応じて続行できます。

これをファイルに入れて、たとえばtest.shと呼びます。

_#!/usr/bin/env sh

# Try to execute a `return` statement,
# but do it in a sub-Shell and catch the results.
# If this script isn't sourced, that will raise an error.
$(return >/dev/null 2>&1)

# What exit code did that give?
if [ "$?" -eq "0" ]
then
    echo "This script is sourced."
else
    echo "This script is not sourced."
fi
_

直接実行します:

_Shell-Prompt> sh test.sh
output: This script is not sourced.
_

ソース:

_Shell-Prompt> source test.sh
output: This script is sourced.
_

私にとっては、これはzshとbashで動作します。

説明

returnステートメントは、関数の外部で実行しようとした場合、またはスクリプトがソースされていない場合にエラーを発生させます。シェルプロンプトからこれを試してください。

_Shell-Prompt> return
output: ...can only `return` from a function or sourced script
_

このエラーメッセージを確認する必要はないので、出力をdev/nullにリダイレクトできます。

_Shell-Prompt> return >/dev/null 2>&1
_

終了コードを確認してください。 0はOK(エラーが発生しなかった)を意味し、1はエラーが発生したことを意味します。

_Shell-Prompt> echo $?
output: 1
_

また、サブシェル内でreturnステートメントを実行する必要があります。 returnステートメントが実行するとき。 。 。まあ。 。 。返却値。サブシェルで実行すると、スクリプトから戻るのではなく、そのサブシェルから戻ります。サブシェルで実行するには、$(...)でラップします。

_Shell-Prompt> $(return >/dev/null 2>$1)
_

これで、サブシェルの内部でエラーが発生したため、サブシェルの終了コードを確認できます。これは1である必要があります。

_Shell-Prompt> echo $?
output: 1
_
19
user5754163

FWIW、他の答えをすべて読んだ後、私は次の解決策を思い付きました:

更新:実際に 誰かが別の答えにエラーを見つけました これは私のものにも影響します。ここでの更新も改善されていると思います(興味がある場合は編集を参照してください)。

これはすべてのスクリプトで機能します。#!/bin/bashで始まりますが、別のシェルから供給される場合もあります。

#!/bin/bash

# Function definitions (API) and Shell variables (constants) go here

main()
{
# The script's execution part goes here
}

BASH_SOURCE=".$0" # cannot be changed in bash
test ".$0" != ".$BASH_SOURCE" || main "$@"

最後の2行の代わりに、次の(私の意見では読みにくい)コードを使用して、他のシェルでBASH_SOURCEを設定せず、mainset -eを機能させることができます。

if ( BASH_SOURCE=".$0" && exec test ".$0" != ".$BASH_SOURCE" ); then :; else main "$@"; fi

このスクリプトレシピには次のプロパティがあります。

  • bashによって通常の方法で実行された場合、mainが呼び出されます。これにはbash -x scriptscriptにパスが含まれない)のような呼び出しは含まれないことに注意してください。以下を参照してください。

  • bashをソースとする場合、mainが呼び出されるのは、呼び出し元スクリプトが偶然同じ名前を持つ場合のみです。 (たとえば、それ自体をソースとする場合、またはbash -c 'someotherscript "$@"' main-script args..を経由する場合、main-scriptは、test$BASH_SOURCEと見なされます)。

  • eval以外のシェルによってsourced/executed/read/bashedされた場合、mainは呼び出されません(BASH_SOURCEは常に$0と異なります)。

  • mainは、$0を空の文字列に設定しない限り、bashがstdinからスクリプトを読み取る場合は呼び出されません:( exec -a '' /bin/bash ) <script

  • bashevalで評価した場合(eval "`cat script`"すべての引用符が重要です!)他のスクリプト内から、これはmainを呼び出します。 evalがコマンドラインから直接実行される場合、これはスクリプトがstdinから読み取られる前のケースに似ています。 (BASH_SOURCEは空白ですが、$0は通常、完全に異なるものに強制されない場合は/bin/bashです。)

  • mainが呼び出されない場合、true$?=0)が返されます。

  • これは予期しない動作に依存していません(以前は文書化されていませんが、unsetBASH_SOURCEも変更できない文書は見つかりませんでした)。

    • BASH_SOURCEはbash予約済み配列です 。しかし、BASH_SOURCE=".$0"の変更を許可すると、非常に危険なワームの缶が開かれるので、これは何の効果もないはずです(おそらく、bashの将来のバージョンでいくつかのい警告が表示されることを除く)。
    • BASH_SOURCEが関数の外で機能するというドキュメントはありません。ただし、その逆(関数でのみ機能する)は文書化されていません。観察は、それが動作することです(bash v4.3およびv4.4でテストされましたが、残念ながらbash v3.xはありません)、$BASH_SOURCEが動作を停止すると、非常に多くのスクリプトが壊れます。観察されたように。したがって、私の期待は、BASH_SOURCEbashの将来のバージョンでもそのままであるということです。
    • 対照的に(いいですね、ところで!)( return 0 )を検討してください。これは、ソースになっている場合は0を、ソースになっていない場合は1を提供します。 これは私にとってだけでなく、少し予期せぬことです 、そして(そこの読みによると)POSIXは、サブシェルからのreturnは未定義の動作であると言います(そしてここのreturnは明らかにサブシェルから)。おそらく、この機能は最終的に十分に広く使用されるため、変更できなくなりますが、AFAICSでは、将来のbashバージョンがその場合の戻り動作を誤って変更する可能性がはるかに高くなります。
  • 残念ながらbash -x script 1 2 3mainを実行しません。scriptにパスがない場合のscript 1 2 3と比較してください)。回避策として次を使用できます。

    • bash -x "`which script`" 1 2 3
    • bash -xc '. script' "`which script`" 1 2 3
    • bash script 1 2 3mainを実行しないことは、機能と見なすことができます。
  • ( exec -a none script )mainを呼び出すことに注意してください(bashはスクリプトに$0を渡しません。このため、最後の点に示すように-cを使用する必要があります)。

したがって、いくつかのコーナーケースを除き、mainは、スクリプトが通常の方法で実行されたときにのみ呼び出されます。 通常、これはあなたが望むものです、特にコードを理解するのが難しい複雑さが欠けているためです.

Pythonコードに非常に似ていることに注意してください:

if __== '__main__': main()

また、スクリプトをインポート/ロードし、その__name__='__main__'を強制できるため、一部の例外的な場合を除いて、mainの呼び出しも防止します。

なぜこれが課題を解決するための良い一般的な方法だと思うのか

複数のシェルから調達できるものがある場合は、互換性がなければなりません。ただし(他の回答を読んで)、sourceingを検出する(実装しやすい)ポータブルな方法がないため、ルールを変更する必要があります

スクリプトを/bin/bashで実行する必要があることを強制することで、まさにこれを行います。

これは以下を除くすべてのケースを解決します。この場合、スクリプトは直接実行できません。

  • /bin/bashがインストールされていない、または機能していない(つまり、ブート環境で)
  • curl https://example.com/script | $Shellのようにシェルにパイプすると

ただし、それを必要とする本当の理由や、まったく同じスクリプトを並行して取得する機能について考えることはできません!通常、それをラップしてmainを手動で実行できます。そのように:

  • $Shell -c '. script && main'
  • { curl https://example.com/script && echo && echo main; } | $Shell
  • $Shell -c 'eval "`curl https://example.com/script`" && main'
  • echo 'eval "`curl https://example.com/script`" && main' | $Shell

ノート

  • この答えは、他のすべての答えの助けなしには不可能だったでしょう!間違ったものであっても-最初はこれを投稿しました。

  • 更新: https://stackoverflow.com/a/28776166/490291 で見つかった新しい発見により編集

8
Tino

BASH固有の回答を提供します。 Korn Shell、ごめんなさい。スクリプト名がinclude2.shであるとします;次に、関数を作成しますinside the include2.sh called am_I_sourcedinclude2.shのデモ版は次のとおりです。

am_I_sourced()
{
  if [ "${FUNCNAME[1]}" = source ]; then
    if [ "$1" = -v ]; then
      echo "I am being sourced, this filename is ${BASH_SOURCE[0]} and my caller script/Shell name was $0"
    fi
    return 0
  else
    if [ "$1" = -v ]; then
      echo "I am not being sourced, my script/Shell name was $0"
    fi
    return 1
  fi
}

if am_I_sourced -v; then
  echo "Do something with sourced script"
else
  echo "Do something with executed script"
fi

今、多くの方法でそれを実行してみてください:

~/toys/bash $ chmod a+x include2.sh

~/toys/bash $ ./include2.sh 
I am not being sourced, my script/Shell name was ./include2.sh
Do something with executed script

~/toys/bash $ bash ./include2.sh 
I am not being sourced, my script/Shell name was ./include2.sh
Do something with executed script

~/toys/bash $ . include2.sh
I am being sourced, this filename is include2.sh and my caller script/Shell name was bash
Do something with sourced script

したがって、これは例外なく機能し、壊れやすい$_を使用していません。このトリックは、BASHのイントロスペクション機能、つまり組み込み変数FUNCNAMEおよびBASH_SOURCE;を使用します。 bashのマニュアルページのドキュメントを参照してください。

注意点は2つだけです。

1)am_I_calledの呼び出しmust実行inソーススクリプト、ただしnot within${FUNCNAME[1]}は何か他のものを返します。ええ...あなたは${FUNCNAME[2]}をチェックできたかもしれませんが、あなたはあなたの人生をより難しくしているだけです。

2)関数am_I_calledmust含まれるファイルの名前を知りたい場合は、ソーススクリプトに常駐します。

5

Dennisの非常に役立つ答え を少し修正することを提案したいと思います。

[ "$_" != "$0" ] && echo "Script is being sourced" || echo "Script is a subshell"

なぜなら[[は(ややアテンキーなIMHO)DebianPOSIX互換シェル、dashによって認識されません。また、スペースを含むファイル名から保護するために引用符が必要になる場合があります。

4
user354193

これはスクリプトの後半で機能し、_変数に依存しません。

## Check to make sure it is not sourced:
Prog=myscript.sh
if [ $(basename $0) = $Prog ]; then
   exit 1  # not sourced
fi

または

[ $(basename $0) = $Prog ] && exit
4
jim mcnamara

$_は非常に脆弱です。スクリプトで最初に行うこととして、これを確認する必要があります。そして、それでも、シェルの名前(ソースの場合)またはスクリプトの名前(実行された場合)を含むことは保証されません。

たとえば、ユーザーがBASH_ENVを設定した場合、スクリプトの先頭にある$_には、BASH_ENVスクリプトで実行された最後のコマンドの名前が含まれます。

私が見つけた最良の方法は、次のように$0を使用することです:

name="myscript.sh"

main()
{
    echo "Script was executed, running main..."
}

case "$0" in *$name)
    main "$@"
    ;;
esac

残念ながら、この方法はfunctionargzeroオプションがその名前が示唆する以上のことを行い、デフォルトでオンになっているため、zshではすぐに機能しません。

この問題を回避するには、unsetopt functionargzero.zshenvに配置します。

2
Mikel

mklement0 compact expression に従いました。

それはきちんとしていますが、次のように起動するとkshの場合に失敗する可能性があることに気付きました。

/bin/ksh -c ./myscript.sh

(ソースであると考えており、サブシェルを実行するためではない)しかし、式はこれを検出するために機能します:

/bin/ksh ./myscript.sh

また、式がコンパクトであっても、構文はすべてのシェルと互換性がありません。

そのため、bash、zsh、dash、およびkshで機能する次のコードで終了しました

SOURCED=0
if [ -n "$ZSH_EVAL_CONTEXT" ]; then 
    [[ $ZSH_EVAL_CONTEXT =~ :file$ ]] && SOURCED=1
Elif [ -n "$KSH_VERSION" ]; then
    [[ "$(cd $(dirname -- $0) && pwd -P)/$(basename -- $0)" != "$(cd $(dirname -- ${.sh.file}) && pwd -P)/$(basename -- ${.sh.file})" ]] && SOURCED=1
Elif [ -n "$BASH_VERSION" ]; then
    [[ $0 != "$BASH_SOURCE" ]] && SOURCED=1
Elif grep -q dash /proc/$$/cmdline; then
    case $0 in *dash*) SOURCED=1 ;; esac
fi

エキゾチックなシェルのサポートを追加してください:)

1

Bash.version> = 3で[mac、linux]で動作するワンライナーが必要でしたが、これらの答えはどれも法案に合いません。

[[ ${BASH_SOURCE[0]} = $0 ]] && main "$@"
0
Karsten

Kshとbashの両方でこれを行うための移植可能な方法はないと思います。 bashではcaller出力を使用して検出できますが、kshに同等のものが存在するとは思いません。

0
Michal Čihař

私は[[ $_ == "$(type -p "$0")" ]]をチェックすることになりました

if [[ $_ == "$(type -p "$0")" ]]; then
    echo I am invoked from a sub Shell
else
    echo I am invoked from a source command
fi

curl ... | bash -s -- ARGSを使用してリモートスクリプトをオンザフライで実行すると、$ 0は実際のスクリプトファイルの実行時に通常の/bin/bashではなくbashになります。したがって、type -p "$0"を使用しますbashの完全なパスを表示します。

テスト:

curl -sSL https://github.com/jjqq2013/bash-scripts/raw/master/common/relpath | bash -s -- /a/b/c/d/e /a/b/CC/DD/EE

source <(curl -sSL https://github.com/jjqq2013/bash-scripts/raw/master/common/relpath)
relpath /a/b/c/d/e /a/b/CC/DD/EE

wget https://github.com/jjqq2013/bash-scripts/raw/master/common/relpath
chmod +x relpath
./relpath /a/b/c/d/e /a/b/CC/DD/EE
0
osexp2003

ポイントまでまっすぐ:変数"$ 0"がシェルの名前と等しいかどうかを評価する必要があります。


このような:

#!/bin/bash

echo "First Parameter: $0"
echo
if [[ "$0" == "bash" ]] ; then
    echo "The script was sourced."
else
    echo "The script WAS NOT sourced."
fi


シェル経由

$ bash check_source.sh 
First Parameter: check_source.sh

The script WAS NOT sourced.

ソース経由

$ source check_source.sh
First Parameter: bash

The script was sourced.



スクリプトがソースされているかどうかを検出する100%ポータブルな方法を設定するのはかなり困難です。

私の経験に関して(Shellscriptingで7年)、唯一の安全な方法(PIDsなどの環境変数に依存しない、これはそれが事実であるため安全ではない) [〜#〜] variable [〜#〜])である必要があります。

  • ifから可能性を広げる
  • 必要に応じて、スイッチ/ケースを使用します。

両方のオプションを自動スケーリングすることはできませんが、より安全な方法です。



例:

SSHセッションを介してスクリプトをソースする場合、変数"$ 0"sourceを使用する場合)によって返される値は- -bash

#!/bin/bash

echo "First Parameter: $0"
echo
if [[ "$0" == "bash" || "$0" == "-bash" ]] ; then
    echo "The script was sourced."
else
    echo "The script WAS NOT sourced."
fi

OR

#!/bin/bash

echo "First Parameter: $0"
echo
if [[ "$0" == "bash" ]] ; then
    echo "The script was sourced."
Elif [[ "$0" == "-bash" ]] ; then
    echo "The script was sourced via SSH session."
else
    echo "The script WAS NOT sourced."
fi
0
ivanleoncz