2015-02-07 170 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