나는 쉘 확장 규칙과 관련이 있다고 생각하는 bash의 신비한 버그를 발견했습니다.왜 bash가 출력에 "ls /"의 출력을 삽입합니까?
다음은 이야기입니다. 회사의 회사 리소스를 조정하기 위해 대규모 내부 웹 사이트를 문서화하는 업무가 있습니다. 안타깝게도이 코드는 오리지날의 목적을 능가하고 회사의 노력을 조정하기위한 주요 자원으로 "진화"함에 따라 상당히 못 생겼습니다.
대부분의 코드는 PHP입니다. 문서 작성을 돕기 위해 몇 가지 도우미 스크립트를 작성했습니다. 예를 들어, 하나의 스크립트는 PHP 함수에서 사용되는 모든 전역 PHP 변수를 추출합니다.
모든 스크립트의 중심에는 "extract_function.sh"스크립트가 있습니다. 기본적으로, 하나의 PHP 함수 이름과 PHP 소스 파일이 주어지면, 그 PHP 함수를 추출하여 출력합니다.
여기에 문제가 있습니다 : 어떻게 든 스크립트가 함수를 추출 할 때 기본적으로 출력 내에 ls /
의 결과를 삽입하는 것입니다. 예를 들어
는 :
$ ./extract_function my_function my_php_file.php
function my_function {
// php code
/etc
/bin
/proc
...
// more php code
}
더욱 혼란스럽게, 나는 단지이 하나 개의 특정 파일에서 하나 개의 특정 기능을 위해 발생하는 쪘 구만! 자, 함수가 꽤 거대하기 때문에 (500 + lines, 나는 코드가 추악하다는 것을 말할 때 그것을 의미합니다!), 나는이 일의 원인을 찾아 내거나, 생각해 낼 수 없었습니다. 이 동작을 생성하는 더 단순한 ad-hoc 함수. 또한 회사 정책에 따라 실제 코드를 공유하지 못하게됩니다. 왜)
1 : 예, 제가 PHP 코드를 조작하는 떠들썩한 파티를 사용하지 않는 것을 알고 있지만, 나는 기본적으로 두 가지 질문이
#!/usr/bin/env bash
program_name=$(basename $0);
function_name=$1;
file_name=$2;
if [[ -z "$function_name" ]]; then
(>&2 echo "Usage: $program_name function_name [file]")
exit 1
fi
if [[ -z "$file_name" ]] || [ "$file_name" = "-" ]; then
file_name="/dev/stdin";
fi
php_lexer_file=$(mktemp)
trap "rm -f $php_lexer_file" EXIT
read -r -d '' php_lexer_text << 'EOF'
<?php
$file = file_get_contents("php://stdin");
$tokens = token_get_all($file);
foreach ($tokens as $token)
if ($token === '{')
echo PHP_EOL, "PHP_BRACKET_OPEN", PHP_EOL;
else if ($token == '}')
echo PHP_EOL, "PHP_BRACKET_CLOSE", PHP_EOL;
else if (is_array($token))
echo $token[1];
else
echo $token;
?>
EOF
echo "$php_lexer_text" > $php_lexer_file;
# Get all output from beginning of function declaration
extracted_function_start=$(sed -n -e "/function $function_name(/,$ p" < $file_name);
# Prepend <?php so that php will parse the file as php
extracted_function_file=$(mktemp)
trap "rm -f $extracted_function_file" EXIT
echo '<?php' > $extracted_function_file;
echo "$extracted_function_start" >> $extracted_function_file;
tokens=$(php $php_lexer_file < $extracted_function_file);
# I've checked, and at this point $tokens does not contain "/bin", "/lib", etc...
IFS=$'\n';
open_count=0;
close_count=0;
for token in $tokens; do # But here the output of "ls /" magically appears in $tokens!
if [ $token = "PHP_BRACKET_OPEN" ]; then
open_count=$((open_count+1))
token='{';
elif [ $token == "PHP_BRACKET_CLOSE" ] ; then
close_count=$((close_count+1))
token='}';
fi
echo $token;
if [ $open_count -ne 0 ] && [ $open_count -eq $close_count ]; then
break;
fi
done
:
그러나, 여기에 내 코드입니다 이 일을하는 bash?
2) 어떻게 해결할 수 있습니까?
'[[-z "$ file_name"]] ||로 무엇을하려합니까? [ "$ file_name"= "-"]; 그때; file_name = "/ dev/stdin"; fi'? – sjsam
@sjsadm 파일 이름이 지정되지 않았거나 '-'와 같으면 stdin에서 읽습니다. '고양이'와 같은 종류의 것도 배관을 더 쉽게 만듭니다. –