私のスクリプトには、 という関数がありますmessages
。これを Linux Mint で記述したところ、問題なく実行できましたが、Debian Buster ステーションに移動したところ、関数が と衝突してしまいました/usr/bin/messages
。
次のスクリプトを呼び出す起動スクリプトがありますmessages
:
スタートアップスクリプト
# call to messages script
. messages
メッセージ
messages() {
# reformat the arguments and return them
}
後でstartup_script
messages "This is a message"
投げる
./startup_script: line 35: .: /usr/bin/messages: cannot execute binary file
messages: could not open mailbox `/path/to/my/script/<string passed to my function>': No such file or directory
/usr/bin/messages
そのため、関数の代わりに呼び出されることに関連するエラーが多数発生します。
を追加した後type messages "This is a message"
、関連する出力は次のようになります。
messages is /usr/bin/messages
関数名を変更するオプションがありますが¹、この状況に対処するにはもっと良い方法があるかもしれません。
スクリプトにシステムバイナリを無視して独自の関数を使用するように指示するにはどうすればよいですか?
¹ この関数は複数のスクリプトで何度も呼び出されるため、名前を変更するだけでは最も簡単なオプションではありません。
答え1
仕組みは以下のとおりです. file
:
<スラッシュ>が含まれていない場合
file
、シェルは指定された検索パスを使用して、PATH
ファイルを含むディレクトリを検索します。
この行動はPOSIXで規定。
最初のエラーは
./startup_script: line 35: .: /usr/bin/messages: cannot execute binary file
次のように呼び出す場合も同様です. echo
:
-bash: .: /bin/echo: cannot execute binary file
バイナリ ファイル をソース化しようとしています/usr/bin/messages
。実際には、関数が定義されているファイルはまったくソース化されておらず、関数は現在のスクリプトで定義されていません。つまり、 later は関数ではなくmessages
を意味します。/usr/bin/messages
関連する行は. ./messages
、または. /full/path/to/messages
(つまり、あなたのバイナリではなくファイルです)。
答え2
エラーメッセージの解釈
エラーメッセージの行番号を確認してくださいそうすれば、どの行にエラーがあるかがわかります。35 行を超えるスクリプトから数行を表示したため、エラーは私たちにはわかりませんでした。
実行されるファイル。
. file-to-source
またはでファイルを指定するとfile-to-run
、環境変数にリストされているディレクトリが$PATH
左から右に検索されます。現在のディレクトリはこのリストに含まれません。セキュリティ上のリスクになるか、少なくとも混乱を招く可能性があるためです。現在のディレクトリでプログラムを実行する場合は、現在のディレクトリにあることを指定する必要があります。例:. ./file-to-source
または./file-to-run
(フルパスを指定する必要はありません)。
.
Unix では、これが問題であると認識されるまで、 が PATH にありました。たとえば、 というプログラムをls
現在のディレクトリに置きます。Microsoft の Windows の CMD では、 が.
暗黙的に に含まれておりPATH
、削除できません。これは、この OS でマルウェアが発生する原因の 1 つです。
落とし穴
.
スクリプトがあるディレクトリではなく、現在の作業ディレクトリを参照します。
それを解決するには、次のようなことを行うことができます。
(
cd "$(dirname "$(readlink -f "$0")")"
script_dir="$(pwd)"
)
script_dir/other_script
誰かがより良い解決策にリンクしてくれることを願っています。