우리는 Red Hat Enterprise Linux 버전 8.5(Ootpa)를 실행하고 있습니다. "yum -y update"를 사용하여 일주일에 한 번 서버를 업데이트할 수 있습니다. 최근에 쉘 명령을 실행할 때 다음 오류가 발생하기 시작했습니다.
- 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 감사합니다!