bash 関数を bash スクリプト内で使用すると、「コマンドが見つかりません」というエラーが発生しますか?

bash 関数を bash スクリプト内で使用すると、「コマンドが見つかりません」というエラーが発生しますか?

関数を作成しaptget、ソースを取得しました:

$ type aptget
aptget is a function
aptget () 
{ 
    sudo apt-get install -y $@
}

スクリプトの最初の数行は次のとおりですbuild.sh

#!/bin/bash

sudo apt remove -y x264 libx264-dev

#aptget build-essential checkinstall cmake pkg-config yasm
aptget git gfortran
aptget libjpeg8-dev libjasper-dev libpng12-dev
aptget libtiff5-dev

aptget libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev
aptget libxine2-dev libv4l-dev

bash スクリプト内で使用しようとすると、aptget見つかりません。

ここに画像の説明を入力してください

たぶん、私はここで何か非常に単純なことを見逃しているのでしょう。これは ですubuntu 18.04。ヒントをいただければ幸いです。

答え1

一般的にシェル関数は、それが定義されているシェルの外部で使用することを意図していないため、この答え正しいです。しかしBashではあなたはこれを行うことができます:

export -f aptget

次に を呼び出すbuild.shと、関数が認識されます。これは、そのインタープリタが であるという事実に依存します。一般に、他のシェルは関数を認識しません。別のインタープリタを使用するようにスクリプトを書き直すと、スクリプト内から をbash呼び出す機能が失われる可能性が高くなります。aptget

一般的な注意: スクリプトの名前はすでに誤解を招くもので、インタープリターが であることを示唆していますsh。スクリプトが大きくなり、pythonなどで書き直す時期が来たとします。他のスクリプトが (明らかに古い名前で) それを使用する可能性があるため、名前を変更せずにこれを実行したいとします。したがって、build.shは良い名前ではありbuildません。良いかもしれません。

標準的な方法は、 という名前のスクリプトを作成しaptget、 が指すディレクトリに配置することですPATH。スクリプトは関数と同じことを行う必要があります。一部の関数はスクリプトで置き換えることができません (たとえば、呼び出し元シェルの変数を操作する場合) が、特定の関数は置き換えることができます。スクリプトを作成した後は、関数自体は不要になります。

その後、aptget別のスクリプトから呼び出されると、正常に動作するはずです。

答え2

シェル関数はサブシェルにエクスポートされません。build.sh が現在のシェル インスタンスで定義されているシェル関数にアクセスできるようにするには、現在のインスタンスで実行されるようにソースを設定する必要があります。通常どおり呼び出すと、新しいシェル インスタンスが起動されて実行され、その新しいサブシェルは現在のシェル インスタンスのシェル関数にアクセスできなくなります。

関連情報