2013-04-16 227 views
1

我寫一個shell腳本,使我有developped作爲運行在Linux上的服務的應用程序。 shell腳本,我寫的作品完全當我用./smpp-daemon.sh開始。然而,當我想用​​下面的語法:SH smpp-daemon.sh開始我得到了以下錯誤:/srv/smpp/bin/smpp-daemon.sh:26:/ SRV/SMPP /斌/ SMPP守護.SH:功能:找不到 /srv/smpp/bin/smpp-daemon.sh:27:地方:沒有的功能。Shell腳本問題

這是shell腳本:

#!/bin/bash 
# 
# Unity SMPP Daemon script 
# 
# Arsene Tochemey GANDOTE 

# Set this to your Java installation 
JAVA_HOME=/usr/lib/jvm/java-7-oracle 

appNameLo="smpp"        # application name with the first letter in lowercase 
appName="SMPP"         # application name 
osUser="root"         # OS user name for the service 
osGroup="root"         # OS group name for the service 
appHome="/srv/$appNameLo"      # home directory of the service application 
osUserHome="/$osUser"       # home directory of the service user 
appLogFile="/var/log/$appNameLo.log"     # log file for StdOut/StdErr 
maxShutdownTime=15         # maximum number of seconds to wait for the daemon to terminate normally 
pidFile="/var/run/$appNameLo.pid"     # name of PID file (PID = process ID number) 
javaCommand="java"         # name of the Java launcher without the path 
javaExe="$JAVA_HOME/bin/$javaCommand"    # file name of the Java application launcher executable 
javaArgs="-jar $appHome/smsgh-smpp.jar"   # arguments for Java launcher 
javaCommandLine="$javaExe $javaArgs"    # command line to start the Java service application 
javaCommandLineKeyword="smsgh-smpp.jar"    # a keyword that occurs on the command line, used to detect an already running service process and to distinguish it from others 

# Makes the file $1 writable by the group $osGroup. 
function makeFileWritable { 
    local filename="$1" 
    touch $filename || return 1 
    chgrp $osGroup $filename || return 1 
    chmod g+w $filename || return 1 
    return 0; 
} 

# Returns 0 if the process with PID $1 is running. 
function checkProcessIsRunning { 
    local pid="$1" 
    if [ -z "$pid" -o "$pid" == " " ]; then return 1; fi 
    if [ ! -e /proc/$pid ]; then return 1; fi 
    return 0; 
} 

# Returns 0 if the process with PID $1 is our Java service process. 
function checkProcessIsOurService { 
    local pid="$1" 
    if [ "$(ps -p $pid --no-headers -o comm)" != "$javaCommand" ]; then return 1; fi 
    grep -q --binary -F "$javaCommandLineKeyword" /proc/$pid/cmdline 
    if [ $? -ne 0 ]; then return 1; fi 
    return 0; 
} 

# Returns 0 when the service is running and sets the variable $pid to the PID. 
function getServicePID { 
    if [ ! -f $pidFile ]; then return 1; fi 
    pid="$(<$pidFile)" 
    checkProcessIsRunning $pid || return 1 
    checkProcessIsOurService $pid || return 1 
    return 0; 
} 

function startServiceProcess { 
    cd $appHome || return 1 
    rm -f $pidFile 
    makeFileWritable $pidFile || return 1 
    makeFileWritable $appLogFile || return 1 
    cmd="nohup $javaCommandLine >>$appLogFile 2>&1 & echo \$! >$pidFile" 
    su -m $osUser -s $SHELL -c "$cmd" || return 1 
    sleep 0.1 
    pid="$(<$pidFile)" 
    if checkProcessIsRunning $pid; then :; else 
     echo -ne "\n$appName start failed, see logfile." 
     return 1 
    fi 
    return 0; 
} 

function stopServiceProcess { 
    kill $pid || return 1 
    for ((i=0; i<maxShutdownTime*10; i++)); do 
     checkProcessIsRunning $pid 
     if [ $? -ne 0 ]; then 
     rm -f $pidFile 
     return 0 
     fi 
     sleep 0.1 
     done 
    echo -e "\n$appName did not terminate within $maxShutdownTime seconds, sending SIGKILL..." 
    kill -s KILL $pid || return 1 
    local killWaitTime=15 
    for ((i=0; i<killWaitTime*10; i++)); do 
     checkProcessIsRunning $pid 
     if [ $? -ne 0 ]; then 
     rm -f $pidFile 
     return 0 
     fi 
     sleep 0.1 
     done 
    echo "Error: $appName could not be stopped within $maxShutdownTime+$killWaitTime seconds!" 
    return 1; 
} 

function startService { 
    getServicePID 
    if [ $? -eq 0 ]; then echo -n "$appName is already running"; RETVAL=0; return 0; fi 
    echo -n "Starting $appName " 
    startServiceProcess 
    if [ $? -ne 0 ]; then RETVAL=1; echo "failed"; return 1; fi 
    echo "started PID=$pid" 
    RETVAL=0 
    return 0; 
} 

function stopService { 
    getServicePID 
    if [ $? -ne 0 ]; then echo -n "$appName is not running"; RETVAL=0; echo ""; return 0; fi 
    echo -n "Stopping $appName " 
    stopServiceProcess 
    if [ $? -ne 0 ]; then RETVAL=1; echo "failed"; return 1; fi 
    echo "stopped PID=$pid" 
    RETVAL=0 
    return 0; 
} 

function checkServiceStatus { 
    echo -n "Checking for $appName: " 
    if getServicePID; then 
    echo "running PID=$pid" 
    RETVAL=0 
    else 
    echo "stopped" 
    RETVAL=3 
    fi 
    return 0; 
} 

function main { 
    RETVAL=0 
    case "$1" in 
     start)            # starts the Java program as a Linux service 
     startService 
     ;; 
     stop)            # stops the Java program service 
     stopService 
     ;; 
     restart)            # stops and restarts the service 
     stopService && startService 
     ;; 
     status)            # displays the service status 
     checkServiceStatus 
     ;; 
     *) 
     echo "Usage: $0 {start|stop|restart|status}" 
     exit 1 
     ;; 
     esac 
    exit $RETVAL 
} 

main $1 

請幫助,因爲我不是shell腳本怪胎。我只能解決問題。

回答

1

的問題是雙重的:

  1. Bash是不是sh在Debian,Ubuntu的,等等,所以當你與sh執行腳本Bashishms將無法正常工作。 Debian使用dash代替sh
  2. local關鍵字是不是,事實上,標準的POSIX sh的。 Dash認爲這是一個函數調用。

簡單的解決方法:不要使用本地,請確保您的變量名稱是唯一的。 Sh腳本不是我的專長,但從我可以告訴它看起來像簡單地刪除有問題的local關鍵字將在您的情況。

+0

事實上,'dash'明白'local'得很好,但不支持'局部變量= value'語法。將它分成'local var; var = value',它應該與Dash一起使用。但它仍然不是POSIX。然而,請參閱http://apenwarr.ca/log/?m=201102#28(特別是項目#4)。 – tripleee

0

作爲./script運行使用#!「shebang」行中聲明的shell,或者如果沒有這樣的行存在,則後者最可能是Bash。

運行作爲sh script覆蓋默認/家當殼,並且使用的是Bourne殼代替 - 或者更可能的是,在擊向後兼容模式。

如果你的腳本使用bash主義(如local),他們不會在第二種情況下工作。

你可以,當然,叫bash script ...

+0

謝謝DevSolar。我使用bash命令,它工作。我也刪除了本地關鍵字。 – Arsene

+0

@BigToch:那麼,*如果*你將它作爲Bash執行,*使用* Bash的特性沒有任何錯誤。與此相反的!這就像是一個使用'char []'而不是'std :: string'的C++程序,所以它可能與C編譯器兼容(它不使用它)。 ;-) – DevSolar