私たちはRed Hat Enterprise Linuxバージョン8.5(Ootpa)を実行しています。 "yum -y update"を使用して、週に1回サーバーを更新できます。最近シェルコマンドを実行すると、次のエラーが発生し始めました。
- sh:ここで:行1:構文エラー:予期しないファイルの終わり
- sh: 'which' の関数定義の取得中にエラーが発生しました。
このエラーを引き起こす可能性がある変更が何であるかはわかりません。だから、システムアップデートをyumとして指定することです。私たちのコードの多くはPHPで書かれており、ここでpassthru()を使用してシェルコマンドを実行します。シェルスクリプトをほとんど書かない場合は、通常bashを使用します。
passthru()を使用してPHPスクリプトを実行する前に、「unset which」を使用してこれらのエラーを回避できました。私たちは多くのスクリプトで多くのシェルコマンドを実行します。これらの各スクリプトを更新するのは効率的なソリューションではありません。時間がかかり、バグが発生する可能性があります。
興味深いことに、次のコードはエラーを引き起こしません。
#!/bin/sh
echo hello
シェルが実行されるたびに実行されるようにシステムまたはユーザーレベルで一度「オフにする」方法はありますか?おそらく、変更可能なシェル設定ファイルやそれに似たものがあるかもしれません。
アップデート1
/etc/profile.d/which2.sh で以下を見つけました。
# shellcheck shell=sh
# Initialization script for bash, sh, mksh and ksh
which_declare="declare -f"
which_opt="-f"
which_shell="$(cat /proc/$$/comm)"
if [ "$which_shell" = "ksh" ] || [ "$which_shell" = "mksh" ] || [ "$which_shell" = "zsh" ] ; then
which_declare="typeset -f"
which_opt=""
fi
which ()
{
(alias; eval ${which_declare}) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot "$@"
}
export which_declare
export ${which_opt} which
ここでは構文が正しいようです。 「which」をエクスポートするのがわかりますが、理由はよくわかりません。それが何であるかを知っていれば、リスクを評価できますunset which
。
アップデート2
小さなPHPスクリプトを作成しました。
#!/usr/bin/php
<?php
passthru('echo hello');
?>
これによりエラーが発生します。
答え1
エラーメッセージは、Bashが環境を介してシェル機能をサブシェルにエクスポートしてインポートできることを意味します。値がで始まるのと同じ名前の環境変数を読み取り、それを関数定義に解析しようとします。BASH_FUNC_funcname%%
() {
このエラーは、定義にエラーがあることを示します。たとえば、閉じるステートメントがないため、エラーが発生する可能性があります}
。ここで() { echo hi;
Bashがこれを見ると、環境変数には次の文字列が含まれます。
$ perl -e '$ENV{"BASH_FUNC_which%%"} = "() { echo hi;"; exec("/bin/bash")'
bash: which: line 1: syntax error: unexpected end of file
bash: error importing function definition for `which'
unset which
関数が定義されていないためエクスポートされません。しかし、これはPHPでシェルが起動したときに定義が壊れる理由を説明していません。 PHPやPHPプログラムが環境変数として何をしているのかはわかりませんが、Bashがエクスポートした関数の環境変数に改行文字を使用している可能性があります。たとえば、
$ which() { echo hi; }
$ export -f which
$ env |grep which -A1
BASH_FUNC_which%%=() { echo hi
}
最初の行だけを見ると、上記のPerlスクリプトのように定義が壊れていました。あなたはそれを調査したいかもしれません。
このwhich
関数のソースは、シェルの初期化ファイル、つまり/etc/bash.bashrc
などを見てください。アイデアを見る環境変数のソースを確認するには?、機能に対しても機能する必要があります。 (怠惰な最初の試みgrep -re which /etc
:)
答え2
unset which
回避策としてこれを.bashrcに入れました。これはbashとPHPの両方で動作します。今朝私はunset which
.bashrcをコメントアウトしました。問題はもう存在しません。この問題は、アップストリームコードの変更によって発生し、解決されたと思います。 @ilkkachu ありがとうございます!