Io-Redirection

在 ksh 中使用 -i 選項(從文件讀取 sql)執行 sqlcmd 後文件描述符和/或 I/O 流的意外行為會創建無限循環

  • September 23, 2016

有沒有辦法使用sqlcmdwith-i input_file選項而不在我的 ksh 腳本中創建無限循環?

  • 程式碼從中讀取行$file並逐行解析以提取數據並處理其他內容。
  • 它使用文件描述符重定向來“$file從”讀取stdin

無限循環程式碼:

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!"

輸出:

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

解決方法(使用此處的文件而不是-i input_file選項):

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!"

輸出:

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

即使有解決該問題的方法,我也想知道這種行為的原因是什麼,以及如何在sqlcmd不禁止該-i input_file選項的情況下使用該工具。

筆記:

  • 適用於 SQL Server 的 Microsoft ODBC 驅動程序 11。
  • 紅帽企業 Linux 6.7 (KornShell)。

正如評論中提到的@meuh,sqlcmd正在閱讀標準輸入,所以附加</dev/null解決了這個問題。問題是while循環正在迭代stdin(以前從 file 重定向exec 0<"${file}"),並且在嘗試從stdinsqlcmd讀取的內部。解決方案是讓to 讀取而不是stdinwhile``sqlcmd``/dev/null

使固定

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!"

引用自:https://unix.stackexchange.com/questions/311251