我正在尝试运行连接到数据库的shell命令(当前为library(tidyverse)
df1 %>%
separate(names, into = c("first_names", "last_names")) %>%
anti_join(df2) %>%
unite(unique_names, sep = " ")
或sh
)。由于数据库仍在“预热”,因此命令失败。
所以我试图做一个循环(比方说... 100次尝试),每次命令失败时,请等待1秒钟然后重试。
如果有错误,这是转储到stdout的字符串的开头:bash
这就是我一直在尝试的:
Sqlcmd: Error: <snipped>
当我发现带有shell / bash的字符串比较的东西时,它不起作用...但是要确保我走的路正确等等。
答案 0 :(得分:2)
您可以尝试以下方法:
while true ; do
if Sqlcmd xxx xxx xxx ; then break ; fi
# or:
Sqlcmd xx xxx xxx && break
sleep 1
done
您还可以添加一个计数器:
for ((n=100;n>0;n--)) ; do
Sqlcmd xxx xxx xxx
if [[ $? == 0 ]] ; then
break
fi
sleep 1
done
[[ $n == 0 ]] && echo Timeout && exit 1
我在这里展示了两种测试返回值的不同方法,但是首选第一种(if cmd ; then ... ; fi
)。
$?
是最后一条命令的返回值,该命令成功完成时为0
。如果即使发生错误(格式错误的程序也可能发生),它仍返回0
,则可以使用grep
测试输出:
Sqlcmd xxx xxx 2>&1 | grep <error pattern> > /dev/null
if [[ $? != 0 ]] ; then break ; fi
我们在这里测试$? != 0
,因为发现错误模式 时grep
将返回0
。
如果要将输出结果转换为变量,请使用X=$(Sqlcmd xxx xxx)
运行命令。然后您可以使用bash字符串比较:
X=$(Sqlcmd xxx xxx)
if [[ "$X" =~ .*error.* ]] ; then
<handle error here>
fi
请注意bash可以match regexp,这使得检查错误类型非常方便。
您还可以使用switch/case
构造:
case "$X" in
*Error:*) echo " Error detected " ;;
*) break ;;
esac
(请注意双;;
)
答案 1 :(得分:1)
我最终了解了所有线索from @matthieu's post。这就是我最终要做的:
for i in $(seq 1 30)
do
/opt/mssql-tools/bin/sqlcmd -U sa -P <snip> -S localhost -Q "USE Master" 2>&1
if [[ $? != 0 ]]
then
# Failed
echo "."
sleep 1s
else
# worked!
break
fi
done
像我这样的学习者的细分
sqlcmd
命令执行sql查询。通过stderr
(即2
中的2>&1
)出现的任何错误都将重定向到控制台stdout
(即$1
)。参考:2>&1 shell idiom。 $?
(REF:what is bash dollar questionmark?)所以我们有了它! shell / bash shell 101的东西。祝你好运!