我有一个bash脚本,在行
上显示“Segment Violation”sp-sc-auth "${sopUrl}" 8809 8908 > /dev/null &
但是从终端执行sp-sc-auth
时工作正常
我设置:
set -o pipefail
set -o errexit
set -o xtrace
set -o nounset
结束脚本继续执行但抛出“Segment Violation”错误...
系统是debian 64位
提前致谢 Regars
丑陋的代码:
#!/usr/bin/env bash
# Init
set -o pipefail
set -o errexit
#set -o xtrace
set -o nounset
__DIR__="$(cd "$(dirname "${0}")"; echo $(pwd))"
__BASE__="$(basename "${0}")"
__FILE__="${__DIR__}/${__BASE__}"
ARG1="${1:-Undefined}"
display_usage() {
scriptName=$(basename $0)
echo -e "Uso:\n "${scriptName}" [6,7,8,9,10 o 12]"
echo "Sin especificar el canal, búsqueda de retransmisiones"
}
parse_arenavision() {
url="http://www.arenavision.in/agenda"
if ! av=$(curl -s "${url}");then
echo "Sin conexión"
exit 1
fi
started="off"
declare -a _list
element=""
while read line
do
if [[ $line =~ (([0-9][0-9]+/[0-9]+/[0-9]+.*)) ]]; then
element=$(echo "${BASH_REMATCH[0]}" | sed -r 's#CET|AV([^6789]|1[02])##g; s#<br />##g; s#//|&.*;##g; s#/\s*$##g; s#INGLATERRA/PREMIER LEAGUE#PREMIER#g; s#ITALIA/SERIE A#SERIE A#g; s#ITALIA/SERIE A#SERIE A#g;' | tr -dc '[:print:]')
if [[ "${element}" =~ (.*AV[6789]|.*AV10|.*AV12) ]]; then
_list+=("${element}")
fi
started="on"
else
if [[ ${started} == "on" ]]; then
break
fi
fi
done <<< "${av}"
for i in "${_list[@]}"; do
if [[ "${i}" =~ (.*BALONCESTO.*) ]]; then
echo -e "\e[92m${i}\e[0m"
elif [[ "${i}" =~ (.*LIGA BBVA.*) ]]; then
echo -e "\e[37m${i}\e[0m"
else
echo "${i}"
fi
done
}
case $ARG1 in
"Undefined" )
parse_arenavision
exit 0
;;
[6789] )
page="${ARG1}"
;;
10 )
page="${ARG1}"
;;
* )
display_usage
exit 1
;;
esac
# Delete "zombies"
if pgrep -f "sp-sc"
then
kill -9 `pgrep -f "sp-sc-auth"`
fi
url="http://www.arenavision.in/arenavision$page"
# Get url content and url sop
if ! content=$(curl -s "${url}");then
echo "Sin conexión"
fi
if [[ $content =~ (sop://([A-Za-z0-9_]+|\.)+:[0-9]+) ]]; then
sopUrl=${BASH_REMATCH[1]}
else
echo "No se ha encontrado la url"
exit 1
fi
# Connect ArenaVision 1
children=""
trap 'kill $children 1>/dev/null 2>&1; exit 143' EXIT
sp-sc-auth "${sopUrl}" 8809 8908 > /dev/null &
children="$!"
# Check if exists
line='[ ]'
for i in {0..15}
do
replace="${line/ /#}"
line=$replace
echo -ne "Comprobando sopcast ${replace}" \\r
sleep 1
done
echo -ne "\033[2K"
if ! kill -0 "${children}" 1>/dev/null 2>&1; then
echo "Sin emisión"
exit 1
else
echo -ne "Comprobando sopcast [ OK ]" \\r
echo
fi
# Open VLC player
line='[ ]'
for i in {0..25}
do
replace="${line/ /#}"
line=$replace
echo -ne "Cargando reproductor ${replace}" \\r
sleep 1
done
if ! kill -0 "${children}" 1>/dev/null 2>&1; then
echo "Fallo en recepción"
exit 1
else
vlc http://localhost:8908/tv.asf 1>/dev/null 2>&1
echo -ne "\033[2K"
fi
exit 0
答案 0 :(得分:1)
errexit
无法处理在后台运行的程序,所以这并不奇怪 - 内联命令只是启动后台进程,并且(启动后台进程)成功,即使过程本身随后失败。
如果您随后致电wait $!
,则然后 errexit
将能够生效,因为wait
来电将以程序的退出状态退出本身。 (当然,如果你可以调用wait $!
,那么就会提出你为什么要开始初始化程序的问题。
如果你总是想要在孩子失败时杀死父脚本,你可以这样做:
(sp-sc-auth "$sopUrl" 8809 8908 >/dev/null || kill $$) &
$$
计算父shell的PID,而不是子shell,因此这将采取相应的行动。
至于段错本身,“程序X段错误”是一个太模糊的问题,无法在这里解决。要开始调试,你需要收集在失败时创建的核心转储(如有必要,启用核心),安装sopcast的调试符号,并使用gdb从失败时创建的核心文件中收集堆栈跟踪。