2015-02-07 171 views
-1

我有一个bash脚本,显示上线“段冲突”分段故障

sp-sc-auth "${sopUrl}" 8809 8908 > /dev/null & 

但当sp-sc-auth从终端执行工作正常

我设置:

set -o pipefail 
set -o errexit 
set -o xtrace 
set -o nounset 

结束脚本继续执行,但会抛出“段违例”错误...

的是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

我猜对了你的母语是Python吗? :) – 2015-02-07 15:24:54

+0

无论如何 - 'kill -0 $ children'检查应该检测到段错误发生的时间,让你的代码在那里出错。 – 2015-02-07 15:25:57

+0

顺便说一句,我会建议退出使用'echo -e'的习惯 - 请参阅POSIX规范中的echo,http://pubs.opengroup.org/onlinepubs/009604599/utilities/ echo.html,特别是APPLICATION USAGE部分; 'echo -e'与纯POSIX和XSI扩展POSIX不兼容。 'printf'是迄今为止更便携的工具。 – 2015-02-07 15:27:21

回答

1

errexit可以在后台运行的程序没有工作,所以这是不足为奇的 - 的内联命令只是简单地启动一个后台进程,并且(启动后台进程)成功,即使进程本身后来失败。

如果你打电话wait $!随后,然后errexit就能生效,因为wait通话将与程序本身的退出状态退出。 (当然,如果你可以请致电wait $!,那么这就提出了你为什么要为最初的程序开始背景的问题)。


如果你总是想,如果孩子不杀父脚本,你可以这样做,而不是:

(sp-sc-auth "$sopUrl" 8809 8908 >/dev/null || kill $$) & 

$$评估父外壳,而不是子shell的PID,所以这将采取相应行动。


至于segfault本身,“program X segfaults”这个问题太模糊了,不能在这里解决。要开始调试,您需要收集在发生故障时创建的核心转储(如有必要,启用核心),安装sopcast的调试符号,并使用gdb从失败时创建的核心文件收集堆栈跟踪。

+0

谢谢Charles !,我在后台运行sp-sc-auth,因为我不知道bash,我需要这个程序在运行vlc前播放流媒体时运行。我在编辑评论中向你展示我的丑陋代码: – Diomedes 2015-02-07 14:51:54