Автор Тема: Странен проблем с shell script  (Прочетена 1959 пъти)

Ali Nebi

  • Напреднали
  • *****
  • Публикации: 394
  • Distribution: Centos, Debian, Fedora, Ubuntu
  • Window Manager: Gnome
    • Профил
Странен проблем с shell script
« -: Jun 16, 2014, 22:25 »
Здравейте,

имам много странен проблем с шел скипт и ще се радвам на вашата помощ. Идеята е следната - имам инит главен инит скрипт, който извиква допълнителни инит скриптове в един цикъл, за да пусне съответните приложения.

Пример:
Код:
for INIT in $(ls $INIT_DIR); do
                $INIT_DIR/$INIT start;
done

Проблемът, който се появява е следният. В скриптовете, които се извикват в цикъла имам return и exit в зависимост от това коя част се изпълнява в процеса на извикване. При първата итерация първият скрипт се изпълнява и цикълът приключва, което не е правилно, защото в самата директория има и други скриптове - ls ги връща. Потествах малко и се оказа, че проблемът се получава от return и exit редовете в скрипта и поради някаква причина това причинява изход от цикъла.

Ще се радвам ако ми дадете идеи къде евентуално бъркам. Между другото ако си ги пускам инит скриптовете на приложенията ръчно през терминала, то те си работят без проблем.

Благодаря предварително!
Активен

Не се задоволявай да бъдеш дим, когато можеш да бъдеш огън!

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Re: Странен проблем с shell script
« Отговор #1 -: Jun 16, 2014, 22:35 »
Налага се да бъдеш по-подробен в показването на код от скрипта. Информацията, която си предоставил дотук, изисква познания по мистични науки, за да се разбере цялата картинка ;)
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

Ali Nebi

  • Напреднали
  • *****
  • Публикации: 394
  • Distribution: Centos, Debian, Fedora, Ubuntu
  • Window Manager: Gnome
    • Профил
Re: Странен проблем с shell script
« Отговор #2 -: Jun 16, 2014, 22:48 »
Извинявам се за това и благодаря за преместването на темата в правилната категория.

Имам един init script в /etc/init.d/javapps.sh който ще се стартира при старт на сървъра. Идеята вътре в него да извиквам старт скриптове на няколко liferay инсталации (томкат), чиито инит скриптове се намират в /var/www/javapps/init.d/enabled директорията.

Главният инит скрипт има следния код:

Код:
#!/bin/bash -e

### BEGIN INIT INFO
# Provides:          javapps
# Required-Start:    $syslog $time $remote_fs
# Required-Stop:     $syslog $time $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: start Java Applications
# Description:       Debian init script for starting Java Applications
### END INIT INFO

DESC="Starting Java Applications"

# Name of the user to run as
USER=javapps

# Location of applications init directory
INIT_DIR=/var/www/javapps/init.d/enabled

RETVAL=0

. /lib/lsb/init-functions

if [ ! -e "$INIT_DIR" ]; then
         log_daemon_msg "Unable to locate init scripts directory. Please set INIT_DIR variable."
         exit 1
fi

start() {
        echo "Starting $DESC: "
        su -s /bin/bash -c "for INIT in $(ls $INIT_DIR); do $INIT_DIR/$INIT status; done" $USER >/dev/null
}

stop() {
        echo "Shutting down $DESC:"
        su -s /bin/bash -c "for INIT in $(ls $INIT_DIR); do $INIT_DIR/$INIT stop; done" $USER >/dev/null
}

status() {
        for INIT in $(ls $INIT_DIR); do
                $INIT_DIR/$INIT status;
        done
}

case "$1" in
  # Start command
  start)
        start
        log_end_msg $?
    ;;
  # Stop command
  stop)
        stop
        log_end_msg $?
    ;;
   # Restart command
   restart)
        stop
        sleep 5
        start
        ;;
   status)
        status
        ;;
  *)
    echo "Usage: /etc/init.d/$NAME {start|restart|stop|status}"
    exit 1
    ;;
esac
 
exit 0


Това е кодът на един от инит скриптовете (всички останали са много подобни на този), който се извикват от този /etc/init.d/javapps.sh във for цикъла:

Код:
#!/bin/bash -e

NAME=cbox-dev
DESC="Liferay CBOX Dev Build"
PIDFILE=/run/javapps/$NAME.pid

# Location of Java JDK
export JAVA_HOME=/var/www/javapps/tools/java7/jdk7

# Location of application's bin directory
CATALINA_HOME=/var/www/javapps/dev/liferay/centricbox/liferay-portal-6.1.1-ce-ga2/tomcat-7.0.27
CATALINA_START=bin/startup.sh
CATALINA_STOP=bin/shutdown.sh
PIDOF=/bin/pidof
RM=/bin/rm
CAT=/bin/cat

RETVAL=0

. /lib/lsb/init-functions

start() {
        log_daemon_msg "Starting $DESC ($NAME): "
        if [ ! -e "$CATALINA_HOME/$CATALINA_START" ]; then
                log_daemon_msg "Unable to locate starting script. Please set CATALINA_START variable."
                return 1
        fi

        if [ -f $PIDFILE ]; then
                PID=$($CAT $PIDFILE)
                RETVAL=$($PIDOF $PID)
                if [ $RETVAL -eq 1 ]; then
                        log_daemon_msg "$DESC is already running..."
                        return 1
                else
                        $RM -f $PIDFILE
                fi
        fi

        $CATALINA_HOME/$CATALINA_START > /dev/null
        RETVAL=$?
        [ $RETVAL -eq 0 ] && echo $! > $PIDFILE

        return $RETVAL
}

stop() {
        log_daemon_msg "Shutting down $DESC ($NAME): "
        if [ ! -e "$CATALINA_HOME/$CATALINA_STOP" ]; then
                log_daemon_msg "Unable to locate stoping script. Please set CATALINA_STOP variable."
                return 1
        fi

        if [ ! -f $PIDFILE ]; then
                echo "Unable to find PID file, $DESC is not running..."
                return 1
        else
                $CATALINA_HOME/$CATALINA_STOP > /dev/null
                RETVAL=$?
                [ $RETVAL -eq 0 ] && $RM $PIDFILE
                return $RETVAL
        fi
}

status() {
        if [ ! -f $PIDFILE ]; then
                log_daemon_msg "Unable to find PID file, $DESC is not running..."
                return 1
        else
                log_daemon_msg "$DESC is running..."
                return 0
        fi
}


case "$1" in
  # Start command
  start)
        start
        log_end_msg $?
    ;;
  # Stop command
  stop)
        stop
        log_end_msg $?
    ;;
   # Restart command
   restart)
        stop
        sleep 5
        start
        ;;
   status)
        status
        ;;
  *)
    echo "Usage: /etc/init.d/$NAME {start|restart|stop|status}"
    exit 1
    ;;
esac
 
exit 0

В главният скрипт, който е предназначен да се пуска при старт на сървъра, има FOR цикъл, но спира веднага след първата итерация, без значение колко скрипта има в директорията, където се намира.

Активен

Не се задоволявай да бъдеш дим, когато можеш да бъдеш огън!

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Re: Странен проблем с shell script
« Отговор #3 -: Jun 17, 2014, 10:25 »
Не съм стигнал да огледам подробно втория скрипт, но в първия на първо четене виждам 2 грешки:
1. В start() функцията си сложил изпълнение на скриптовете със status параметър. Не е това проблемът, заради който питаш, но да кажа;
2. При така организираните шелове променливата $INIT_DIR остава недефинирана във for циклите, при което се листват файловете не в очакваната "/var/www/javapps/init.d/enabled", а в директорията, от която скриптът се изпълнява. Това със сигурност е проблем за очакваното изпълнение на скрипта, а в определени ситуации може да доведе и до точния проблем, който се проявява при теб. За да бъде четимо съдържанието на променливата $INIT_DIR от for циклите в текущата организация може да опишеш тези редове така
Цитат
su -s /bin/bash -c 'for INIT in $(ls '$INIT_DIR'); do '$INIT_DIR'/$INIT status; done' $USER >/dev/null
Обърни внимание, че кавичките са станали единични и са добавени нови!

Оправи тези два проблема, виж как е и ще го мислим нататък, ако все още имаш проблем!
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

Ali Nebi

  • Напреднали
  • *****
  • Публикации: 394
  • Distribution: Centos, Debian, Fedora, Ubuntu
  • Window Manager: Gnome
    • Профил
Re: Странен проблем с shell script
« Отговор #4 -: Jun 17, 2014, 11:33 »
Здравей,

Благодаря ти за бързия отговор и за помощта. Направих нужните промени, както ме посъветва и сега всичко работи правилно. Не очаквах, че INIT_DIR ще бъде недефинирана по начина по който го бях писал - научих нещо ново. :) Предполагам, че ако се сложи export пред дефиницията на INIT_DIR, то тогава ще е видима, дори и без промяна и добавка на кавичките (разбира се това не е добра идея, но пусто любопитство :) ).

Благодаря още веднъж neter и успешен ден!
Активен

Не се задоволявай да бъдеш дим, когато можеш да бъдеш огън!

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Re: Странен проблем с shell script
« Отговор #5 -: Jun 17, 2014, 13:49 »
Предполагам, че ако се сложи export пред дефиницията на INIT_DIR, то тогава ще е видима, дори и без промяна и добавка на кавичките
Може и така - в случая не се съдържа чувствителна информация в нея, което да понижи по някакъв начин сигурността. Само не забравяй после да unset-неш променливата, защото ще си остане излишно в средата и след края на изпълнението на скрипта. Имай предвид обаче, че това ще ти спести добавените нови два чифта кавички, но все още се налага основните кавички да бъдат единични, тъй като при двойни това, което излиза от командата ls, ще бъде възприемано като параметри, а не като текст, който да използваш в структурата на имената след това.

Иначе, аз на твое място бих изкарал променливата $INIT_DIR извън тези редове и бих заменил for-овете с while. Например:
Цитат
cd "$INIT_DIR"
su -s /bin/bash -c 'ls | while read INIT; do "$(pwd)/$INIT" status; done' $USER >/dev/null
Този вариант като цяло ти решава и още един проблем - евентуални интервали в имената на папката и файловете. Първата команда е най-добре да отиде точно под задаването на стойността на $INIT_DIR.

Успех и на теб ;)
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
rc.d shell script
Настройка на програми
VlasA 3 2860 Последна публикация Aug 29, 2004, 12:05
от VlasA
Shell-script- за минаване от един юзър в друг
Настройка на програми
Nik123 5 3576 Последна публикация Jul 03, 2006, 20:22
от Nik123
shell script с параметри
Общ форум
k0tka 1 2891 Последна публикация May 25, 2012, 20:23
от k0tka
shell script
Общ форум
villimon 29 10618 Последна публикация Nov 01, 2013, 21:43
от neter
ПРЕМЕСТЕНО: shell script
Общ форум
neter 0 1897 Последна публикация Oct 18, 2013, 22:59
от neter