2013-04-16 8 views
1

J'écris un script shell pour faire fonctionner une application que j'ai développée en tant que service sous Linux. Le script shell que j'ai écrit fonctionne parfaitement lorsque j'ai utilisé le ./smpp-daemon.sh start. Cependant, lorsque je veux utiliser la syntaxe suivante: sh smpp-daemon.sh start J'ai l'erreur suivante: /srv/smpp/bin/smpp-daemon.sh: 26:/srv/smpp/bin/smpp-daemon .sh: function: non trouvé /srv/smpp/bin/smpp-daemon.sh: local: pas dans une fonction.Problème de script Shell

C'est le script 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 

S'il vous plaît aider parce que je suis pas geek débourser script. Je peux seulement me débrouiller.

Répondre

1

La question est double:

  1. Bash n'est pas sh sur Debian, Ubuntu, etc., donc Bashishms ne fonctionnera pas lorsque vous exécutez votre script avec sh. Debian utilise dash pour sh à la place.
  2. Le mot-clé local n'est pas, en fait, standard POSIX sh. Dash pense que c'est un appel de fonction.

Solution de contournement facile: n'utilisez pas local, assurez-vous que vos noms de variables sont uniques. Sh scripting n'est pas mon fort, mais de ce que je peux dire, il semble simplement supprimer le mot-clé local fautif fera dans votre cas.

+0

En fait, '' dash' comprend local' très bien, mais la syntaxe 'var = de value' local n'est pas pris en charge. Diviser en 'local var; var = value' et ça devrait marcher avec Dash. Ce n'est toujours pas POSIX, cependant. Voir, cependant, aussi http://apenwarr.ca/log/?m=201102#28 (en particulier article # 4). – tripleee

0

Exécution en tant que ./script utilise le shell indiqué dans la ligne "shebang" #!, ou votre shell par défaut si aucune ligne n'existe - ce dernier étant probablement Bash.

Exécuté en tant que sh script remplace le shell par défaut/shebang, et utilise le shell Bourne à la place - ou, plus probablement, Bash en mode de compatibilité descendante.

Si votre script utilise Bash-isms (comme local), ils ne fonctionneront pas dans le second cas.

Vous pouvez, bien sûr, appelez bash script ...

+0

Merci DevSolar. J'utilise la commande bash et cela a fonctionné. Je supprime également le mot clé local. – Arsene

+0

@BigToch: Eh bien, * si * vous l'exécutez comme Bash, il n'y a rien de mal à * utiliser * les fonctionnalités de Bash. Au contraire! Ce serait comme un programme C++ utilisant 'char []' au lieu de 'std :: string' donc il pourrait être compatible avec un compilateur C (qu'il n'utilise pas). ;-) – DevSolar