예상치 못한 EOF 오류가 발생했습니다.

예상치 못한 EOF 오류가 발생했습니다.

다음 오류가 발생합니다.

/tmp/filechecking.sh: line 11: warning: here-document at line 6 delimited by end-of-file (wanted `EOF')
/tmp/filechecking.sh: command substitution: line 8: unexpected EOF while looking for matching `"'
/tmp/filechecking.sh: command substitution: line 11: syntax error: unexpected end of file
/tmp/filechecking.sh: line 6: bad substitution: no closing "`" in `
echo "${filetype[@]}"
done

내 스크립트는

losystem=`ls /appl/vortex/archive/cons/*`
echo "${losystem[@]"
for indsystm in "${losystem[@]}"
do
filetype=`isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select  file_type  from expected_file where  starters_package_version = '4.0' and system_id = 'DAL'
go
EOF`
echo "${filetype[@]}"
done

누구든지 여기서 구문 오류가 무엇인지 도울 수 있습니까?

답변1

losystem=`ls /appl/vortex/archive/cons/*`
echo "${losystem[@]"
for indsystm in "${losystem[@]}"
do
filetype=`isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select  file_type  from expected_file where  starters_package_version = '4.0' and system_id = 'DAL'
go
EOF`
echo "${filetype[@]}"
done

EOF구문 오류 자체는 다음 과 같은 줄에 나타나는 백틱으로 인해 발생합니다 .코살로난다의 답변. 하지만,스크립트에 다른 문제가 있습니다.따라서 쉘 스크립팅 기술을 더 잘 향상시키기 위해 좀 더 자세히 살펴보겠습니다.


첫 번째 오해: 말씀하신 대로 "${losystem[@]}", 당신은배열을 만들었습니다.. 너는 ..하지 않았다. 이렇게 하려면 변수 할당에 괄호를 사용해야 합니다.

마찬가지로, 만약 당신이하다배열을 사용하면 을 사용할 필요가 없습니다 ls. 구는 배열의 요소로 직접 확장됩니다.

ls어쨌든 출력을 구문 분석하면 안 되기 때문에 이는 행운입니다.

따라서 변수를 설정하는 올바른 방법 losystem대량으로그 요소는 그 안에 있는 파일과 디렉터리입니다 /appl/vortex/archive/cons/.

losystem=(/appl/vortex/archive/cons/*)

두 번째 줄의 명령 echo에 종결자가 없습니다 }.

또한 printf여기에서 사용할 수도 있습니다.

printf '%s\n' "${losystem[@]}"

또한보십시오:


루프 for는 Bash 배열의 요소를 반복하는 데 적합 losystem하므로 위의 수정 사항을 적용한 경우 변경하지 않고 사용할 수 있습니다.

그러나 당신은 그러지 않았습니다.필요어레이 등을 설정하세요.구절(더 깔끔하고 직관적) for 루프에서 직접 파일 glob을 선언합니다.

for indsystem in /appl/vortex/archive/cons/*; do

이는 또한 Bash 배열에 의존하지 않는다는 점에서 POSIX와 호환된다는 장점이 있으므로 더 넓은 범위의 셸에서 작동합니다(즉, 이식성이 더 높습니다).


스크립트의 다음 부분은 filetype설정하는 것처럼 보이기 때문에 검토하기가 더 어렵습니다.산출명령했는데 isql넌 안 했어하다인쇄하는 것을 제외한 이 출력의 모든 것(잘못된 형식) echo. (다시 한번 보세요.왜 printf가 echo보다 나은가요?)

가장 확실한 방법은 변수를 전혀 설정하지 않고 명령을 직접 실행하는 것입니다. 그러면 실제로 원하는 대로 자체 출력이 인쇄됩니다.

isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select  file_type  from expected_file where  starters_package_version = '4.0' and system_id = 'DAL'
go
EOF

알아채다나는 그것에 익숙하지 않기 isql때문에 이 명령의 정확성을 증명하지 않습니다. 이것은 귀하가 직접 작성한 명령이며 변경된 사항이 없습니다. 정확할 수도 있고 아닐 수도 있습니다.


하지만 이 스크립트의 가장 이상한 점은 배열 indsystem의 모든 요소를 ​​설정하거나 losystem그렇게 하려고 한다는 것입니다.당신은 가치를 인용하지 않습니다 "$indsystem".

이것은 "방 안의 코끼리"입니다. 나는 당신의 마음을 읽을 수 없기 때문에 이 논리를 고칠 수 없습니다. 무엇을 하고 싶은지 전혀 명확하지 않습니다.

몇 가지 다른 가능성을 생각해 볼 수 있습니다.

  1. isql어쩌면 디렉토리에 있는 모든 파일에 대해 명령을 실행하려고 할 수도 있습니다 cons. (이 경우 isql명령은 어딘가에 있는 변수를 참조해야 하며 indsystem디렉터리에서 실행하고 있지 않은지 확인해야 합니다.)
  2. 디렉토리가 비어 있지 않은 isql경우에만 명령을 한 번만 실행하고 싶을 수도 있습니다 .cons
  3. isql따옴표 없이 명령을 실행 하고 싶을 수도 있지만 indsystem, 디렉토리의 파일/디렉터리와 동일한 방식으로 여러 번 실행하십시오 cons. (이것이 제가 수정한 코드 버전에서 수행할 작업이지만 별 의미가 없습니다.)

이러한 가능성 중 어느 것도 확실히 정확하지 않으므로 스크립트가 실제로 무엇을 하려고 하는지 알 수 없습니다.

그래도 이것이 쉘 스크립팅에 대해 더 많이 배우는 데 도움이 되기를 바랍니다. Bash 스크립팅을 제대로 배우려면 다음을 권장합니다.울위치 카니발 가이드.


나는 또한 내 전문적인 경험을 통해 이 스크립트만큼 많은 문제가 있는 쉘 스크립트에는 일반적으로 아키텍처/디자인 문제가 있다는 것을 발견했다고 말하고 싶습니다.더 높은 수준에서, 그 다음에대개진정으로 실행 가능한 솔루션에 도달하려면 먼저 스크립트가 필요한 이유를 철저하게 검토해야 합니다.

답변2

이 문서의 닫는 구분 기호는 한 줄에 단독으로 표시되어야 합니다.

filetype=`isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select  file_type  from expected_file where  starters_package_version = '4.0' and system_id = 'DAL'
go
EOF
`

$(...)일반적 으로 새 코드에서는 백틱 대신 백틱을 사용하는 것이 좋습니다. $(...)중첩 기능이 더 좋고 일반적으로 보기에도 더 좋기 때문입니다.

filetype=$( isql -UDAS -PCDRD -SYTRT_DCS_FRET <<EOF
select  file_type 
  from  expected_file
  where starters_package_version = '4.0' 
    and system_id = 'DAL'
go
EOF
)

$(...)사용하는 것이 더 나은 이유에 대한 자세한 내용은 "*sh 쉘에서는 백틱(예: "cmd")이 더 이상 사용되지 않습니까?"

관련 정보