obtendo erro EOF inesperado

0

Estou recebendo o seguinte erro

/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

Meu script é

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

Alguém pode ajudar o que é o erro de sintaxe aqui?

    
por Biswaranjan Das 31.01.2017 / 22:52

2 respostas

4

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

O erro de sintaxe é causado pelo backtick que aparece na mesma linha que EOF , conforme indicado na resposta de Kusalananda . No entanto, este script tem outros problemas, por isso, no interesse de melhorar as habilidades de script de shell em todos os lugares, vamos dar uma olhada mais de perto.

Primeiro equívoco: como você faz referência a "${losystem[@]}" , parece que você tem a impressão de ter criado uma matriz . Você não tem. Para fazer isso, você precisa usar parênteses em sua atribuição de variável.

Da mesma forma, se você fizer usar uma matriz, não será necessário usar ls . Os globs se expandirão diretamente para se tornarem os elementos do array.

Isso é uma sorte, porque você nunca deve analisar a saída de ls , de qualquer maneira; veja:

Então, o caminho certo para definir a variável losystem como uma matriz cujos elementos são os arquivos e diretórios dentro de /appl/vortex/archive/cons/ é:

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

Seu comando echo (na segunda linha) está faltando um fechamento } .

Além disso, você pode usar printf aqui:

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

Veja também:

O loop for está correto para iterar os elementos da matriz Bash em losystem , portanto, considerando que você fez as correções acima, você pode usá-lo inalterado.

No entanto, você não precisa para definir um array, e é muito mais idiomático (mais limpo, mais intuitivo) para declarar diretamente o arquivo glob no loop for :

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

Isso também tem a vantagem de ser compatível com POSIX, uma vez que não depende de arrays Bash, para que ele possa trabalhar em uma variedade maior de shells (ou seja, é mais portátil).

A próxima parte do seu script é ainda mais difícil de analisar, porque parece que você está definindo filetype para a saída do comando isql , mas você não o faz > faça qualquer coisa com este resultado, exceto imprimi-lo - mal formatado - com echo . (Novamente, veja Por que printf é melhor que echo? )

A abordagem óbvia não é definir a variável, mas apenas executar o comando diretamente; imprimirá a sua própria saída, o que é tudo o que você realmente quer de qualquer maneira:

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

Note que eu não estou familiarizado com isql , então eu não atesto a exatidão deste comando. É o comando que você mesmo escreveu, inalterado. Pode ou não estar correto.

A coisa mais estranha sobre esse script, porém, é o fato de você estar definindo indsystem para cada elemento da matriz losystem (ou tentando), mas, em seguida, você nunca referencia o valor de "$indsystem" .

Este é o "elefante na sala". Não posso consertar essa lógica, porque não consigo ler sua mente. Não está claro o que você está tentando fazer.

Eu posso pensar em várias possibilidades diferentes:

  1. Talvez você esteja tentando executar o comando isql em cada arquivo no diretório cons . (Nesse caso, o comando isql deve referenciar a variável indsystem em algum lugar, e você deve verificar se não a executa nos diretórios.)
  2. Talvez você queira executar o comando isql exatamente uma vez, mas apenas se o diretório cons não estiver vazio.
  3. Talvez você queira executar o comando isql sem fazer referência a indsystem , mas executá-lo da mesma maneira várias vezes, exatamente quantas vezes houver arquivos / diretórios no diretório cons . (Isso é o que minha versão fixa do código fará, mas não faz muito sentido.)

Nenhuma dessas possibilidades é obviamente correta, então não posso concluir o que o script está realmente tentando fazer.

Ainda assim, espero que isso tenha sido útil para aprender mais sobre scripts de shell. Para aprender o script Bash corretamente, recomendo o Guia do Bash do Wooledge .

Também comentarei que, em minha experiência profissional, descobri que um shell script com tantos problemas quanto este geralmente tem problemas de arquitetura / design em um nível mais alto , e geralmente é necessário rever completamente o suposto motivo pelo qual o script é necessário, em primeiro lugar, para obter uma solução realmente viável.

    
por 31.01.2017 / 23:31
1

O delimitador final do documento here deve estar sozinho na linha:

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
'

Geralmente é recomendado usar $(...) em vez de backticks para novo código, pois $(...) tem melhores recursos de aninhamento e, em geral, parece melhor:

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
)

Para obter informações sobre por que usar $(...) pode ser preferível, consulte " Os backticks (ou seja, 'cmd') nas shells * sh foram preteridos? "

    
por 31.01.2017 / 23:23