BASH: функция не запускается после установки на новый сервер - PullRequest
1 голос
/ 19 марта 2012

Возможно различия BASH?Работает нормально на старом сервере, не работает на новом.

Он никогда не повторяет "сделал это" в функции get_running_palaces (), но вместо этого выводит

comm: / dev / fd / 63: Нет такогофайл или каталог
comm: / dev / fd / 63: Нет такого файла или каталога

#!/bin/bash

TYPE=$1

get_palaces(){
    for PALACE in $(ls -trI shared /home | sort); do
        if [ -d "/home/$PALACE/palace" ]; then
            echo $PALACE
        fi
    done
}
#  comm -12 file1 file2  Print only lines present in both file1 and file2.
# comm -3  file1 file2  Print lines in file1 not in file2, and vice vers
get_running_palaces(){
    echo "made it";
    PSFRONT_A=$(ps ax | grep '[p]sfront -p .* -r /home/.*/palace ' |  sed 's| *\([0-9]*\).*/home/\(.*\)/palace.*$|\2|' | uniq | sort)
    PSERVER_A=$(ps ax | grep '[p]server.* -f /home/.*/palace/psdata/pserver.conf ' | sed 's| *\([0-9]*\).*/home/\(.*\)/palace.*$|\2|' | sort)
    ERRORS=$(comm -3 <(echo "${PSERVER_A[*]}") <(echo "${PSFRONT_A[*]}"))
    if [ ! -z "$ERRORS" ]; then
        comm -3 <(echo "${PSERVER_A[*]}") <(echo "${ERRORS[*]}")
    else
        echo "$PSERVER_A"
    fi

}

case "$TYPE" in
online) 
    KNOWN_PALACES=$(get_palaces)
    ERROR_LESS=$(get_running_palaces)
    ONLINE=$(comm -12 <(echo "${KNOWN_PALACES[*]}") <(echo "${ERROR_LESS[*]}"))

    [ ! -z "$ONLINE" ] && echo "$ONLINE"
    ;;
offline)    
    KNOWN_PALACES=$(get_palaces | sort)
    ERROR_LESS=$(get_running_palaces)

    OFFLINE=$(comm -3 <(echo "${KNOWN_PALACES[*]}") <(echo "${ERROR_LESS[*]}"))

    [ ! -z "$OFFLINE" ] && echo "$OFFLINE"
    ;;
*)  
    get_palaces
    ;;
esac


exit 0;

Информация:

Новый сервер:


uname -a
Linux www.ipalaces.org 2.6.32-274.7.1.el5.028stab095.1 # 1 SMP Пн 24 октября 20:49:24 MSD 2011 x86_64 GNU / Linux
lsb_release -rd
-bash: lsb_release: команда не найдена
bash --version
GNU bash, версия 4.1.5 (1) -выпуск (x86_64-pc-linux-gnu)


Старый сервер:

uname -a
Linux ipalaces.org 2.6.32-5-686 # 1 SMP Пн 16 января 16:04:25 UTC 2012 i686 GNU / Linux
lsb_release -rd
Описание: Debian GNU / Linux 6.0.4 (squeeze)
Выпуск:6.0.4

bash - версия
GNU bash, версия 4.1.5 (1) -релиз (i486-pc-linux-gnu)

Ответы [ 2 ]

1 голос
/ 20 марта 2012

Для подстановки процесса требуется /dev/fd/* в Linux (я думаю, что его реализация зависит от того, как построен Bash). Может быть, у вас испорчена структура /dev/ в том месте, где работает этот скрипт? Такие вещи случаются.

Я видел, что bash-скрипты при загрузке не смогли сгенерировать документ здесь, для которого требовалось /tmp, которое еще не было смонтировано (и пришло бы из tmpfs позже, поэтому такого каталога нет в корневой том или где-либо еще).

В этой системе вообще работает подстановка процессов? Я имею в виду, если вы входите в систему, которая работает и работает, вы можете сделать что-то вроде

diff <(echo "a") <(echo "b")

Если это не сработает, вам нужно либо исправить /dev, либо изменить способ сборки Bash (используйте fifo s для подстановки процессов), либо просто изменить свой сценарий, чтобы не полагаться на подстановку процессов.

0 голосов
/ 20 марта 2012

Если вы не можете понять, как включить подстановку процесса в Bash на новом сервере, возможно, вам следует реорганизовать скрипт, чтобы использовать более традиционную модель обработки.По сути, это сводится к использованию временных файлов.

ps ax |
grep '[p]sfront -p .* -r /home/.*/palace ' |
sed 's| *\([0-9]*\).*/home/\(.*\)/palace.*$|\2|' |
uniq | sort >/tmp/PSFRONT_A

ps ax |
grep '[p]server.* -f /home/.*/palace/psdata/pserver.conf ' |
sed 's| *\([0-9]*\).*/home/\(.*\)/palace.*$|\2|' |
sort >/tmp/PSERVER_A

ERRORS=$(comm -3 /tmp/PSERVER_A /tmp/PSFRONT_A)

rm /tmp/PSERVER_A /tmp/PSFRONT_A

Кстати, это полностью POSIX-совместимая программа, поэтому вы можете изменить строку shebang на #!/bin/sh, пока вы там.

Вы должны упростить grep | sed и реорганизовать повторяющиеся функции;Кроме того, правильное использование временных файлов требует использования trap для удаления временных файлов, даже если сценарий прерывается сигналом на полпути.

t=`mktemp -t -d palaces.XXXXXXXX` || exit 127
trap 'rm -rf $t' 0
trap 'exit 126' 1 2 3 5 15

psg () {
    local re
    re=$1
    ps ax |
    sed -n "\\%$re%"'s| *\([0-9]*\).*/home/\(.*\)/palace.*$|\2|p'
}

psg '[p]sfront -p .* -r /home/.*/palace ' |
    uniq | sort >$t/PSFRONT_A
psg '[p]server.* -f /home/.*/palace/psdata/pserver\.conf ' |
    sort >$t/PSERVER_A

comm -3 $t/PSERVER_A $t/PSFRONT_A >$t/ERRORS

if [ -s $t/ERRORS ]; then
    comm -3 $t/PSERVER_A $t/ERRORS
else
    cat $t/PSERVER_A
fi

Остальная часть сценария может быть адаптированасоответственно.

...