Comportamento inesperado de descritor de arquivo e / ou fluxos de E / S depois de executar o sqlcmd com a opção -i (leia sql do arquivo) em ksh cria um loop infinito

2

Existe uma maneira de usar a opção sqlcmd with -i input_file sem criar um loop infinito no meu script ksh?

  • O código lê linhas de $file e analisa linha por linha para extrair dados e processar outras coisas.
  • Ele usa o redirecionamento de descritores de arquivo para "ler o $file do stdin ".

Código de loop infinito:

exec 3<&0
exec 0<"${file}"
while read -r line || [[ -n ${line} ]]
do
    echo "${line}"
    sqlcmd -S svr -U usr -P pwd -i input_file >/dev/null 2>&1
done
exec 0<&3
exec 3<&-
echo "Script completed successfully!"

Saída:

line 1 ...
line 1 ...
...
line 1 ...^C

Solução alternativa (use aqui documento em vez de -i input_file opção):

exec 3<&0
exec 0<"${file}"
while read -r line || [[ -n ${line} ]]
do
    echo "${line}"
    sqlcmd -S svr -U usr -P pwd <<-EOF
        -- SOME SQL CODE HERE
    EOF
    # here document lines are indented with tabs, not whitespaces.
done
exec 0<&3
exec 3<&-
echo "Script completed successfully!"

Saída:

line 1 ...
line 2 ...
line 3 ...
Script completed successfully!

Mesmo que haja uma solução alternativa para o problema, eu gostaria de saber qual é o motivo desse comportamento e como usar a ferramenta sqlcmd sem bani-la da opção -i input_file .

Notas:

  • Microsoft ODBC Driver 11 para SQL Server.
  • Red Hat Enterprise Linux 6.7 (KornShell).
por CamelCamelius 21.09.2016 / 07:48

1 resposta

0

Como @meuh mencionou nos comentários, sqlcmd estava lendo stdin , por isso, anexar </dev/null corrigiu o problema. O problema era que o loop while estava iterando sobre o stdin (anteriormente redirecionado de um arquivo exec 0<"${file}" ) e o sqlcmd que estava dentro do while tentou ler do > stdin . A solução estava fazendo o sqlcmd ler a partir de /dev/null em vez de stdin .

Corrigir

exec 3<&0
exec 0<"${file}"
while read -r line || [[ -n ${line} ]]
do
    echo "${line}"
    sqlcmd -S svr -U usr -P pwd -i input_file </dev/null
done
exec 0<&3
exec 3<&-
echo "Script completed successfully!"
    
por 23.09.2016 / 17:34