Я написал свой первый сценарий bash, который проверяет папки для изменений с помощью функции «inotify» и запускает некоторые действия. Весь процесс запускается nohup в качестве фонового процесса.Unix Bash Script запускается несколько раз даже с PID-файлом
Эта папка является местом назначения нескольких регистраторов данных, которые толкают файлы в zip-формате через ftp в разные подпапки. Сценарий bash распаковывает файлы и запускает php-скрипт впоследствии, который обрабатывает содержимое zip-файлов.
Моей проблема: Иногда сценарий Баша дает мне ошибки, как следующее:
- No zipfiles found.
- unzip: cannot find zipfile...
Это не должно произойти, потому что файлы существуют, и я могу использовать ту же команду в терминале без ошибок. Раньше у меня была такая же проблема, когда я с успехом запускал скрипт несколько раз, поэтому я думаю, что это как-то вызывает проблему.
Я попытался решить проблему с помощью PID-файла, который находится в моем домашнем каталоге. По какой-то причине он по-прежнему запускает два экземпляра сценария bash. Если я попытаюсь запустить другой экземпляр, он покажет предупреждение «Процесс уже запущен», как предполагалось (см. Программный код). Когда я убиваю процесс второго экземпляра вручную (kill $$), он перезапускается через некоторое время, и снова есть два экземпляра процесса.
#!/bin/bash
PIDFILE=/home/PIDs/myscript.pid
if [ -f $PIDFILE ]
then
PID=$(cat $PIDFILE)
ps -p $PID > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "Process already running"
exit 1
else
## Process not found assume not running
echo $$ > $PIDFILE
if [ $? -ne 0 ]
then
echo "Could not create PID file"
exit 1
fi
fi
else
echo $$ > $PIDFILE
if [ $? -ne 0 ]
then
echo "Could not create PID file"
exit 1
fi
fi
while true;
do inotifywait -q -r -e move -e create --format %w%f /var/somefolder | while read FILE
do
dir=$(dirname $FILE)
filename=${FILE:$((${#dir}+1))}
if [[ "$filename" == *.zip ]];
then
unzip $FILE
php somephpscript $dir
fi
done
done
Выход из пса -ef выглядит следующим образом:
UID PID PPID C STIME TTY TIME CMD
root 1439 1433 0 11:19 pts/0 00:00:00 /bin/bash /.../my_script
root 3488 1439 0 15:10 pts/0 00:00:00 /bin/bash /.../my_script
Как вы можете видеть, вторые экземпляры Родитель-PID является сценарием самого
EDIT: Я изменил сценарий Баша как рекомендовал Фред. Исходный код теперь выглядит следующим образом:
#!/bin/bash
PIDFILE=/home/PIDs/myscript.pid
if [ -f $PIDFILE ]
then
PID=$(cat $PIDFILE)
ps -p $PID > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "Process already running"
exit 1
else
## Process not found assume not running
echo $$ > $PIDFILE
if [ $? -ne 0 ]
then
echo "Could not create PID file"
exit 1
fi
fi
else
echo $$ > $PIDFILE
if [ $? -ne 0 ]
then
echo "Could not create PID file"
exit 1
fi
fi
while read -r FILE
do
dir=$(dirname $FILE)
filename=${FILE:$((${#dir}+1))}
if [[ "$filename" == *.zip ]];
then
unzip $FILE
php somephpscript $dir
fi
done < <(inotifywait -q -m -r -e move -e create --format %w%f /var/somefolder)
Выхода пса -ef еще показывает два экземпляра:
UID PID PPID C STIME TTY TIME CMD
root 7550 7416 0 15:59 pts/0 00:00:00 /bin/bash /.../my_script
root 7553 7550 0 15:59 pts/0 00:00:00 /bin/bash /.../my_script
root 7554 7553 0 15:59 pts/0 00:00:00 inotifywait -q -m -r -e move -e create --format %w%f /var/somefolder
Вы говорите, что сценарий, когда он запускается второй раз, отображает предупреждающее сообщение, а затем не останавливается после утверждения «exit 1»? Если вы действительно пытаетесь «убить $$» в своей интерактивной оболочке, это ничего не делает, поскольку $$ - это PID оболочки и оболочка, отправляющая себя, что сигнал ничего не делает. – Fred
Довольно амбициозный для первого сценария, я должен сказать! Внутри условно-одиночных скобок [] вы всегда должны указывать свои переменные, например [-f "$ PIDFILE"]. Ну, вы должны цитировать их почти везде. Обычно рекомендуется использовать имена переменных в нижнем регистре, чтобы избежать конфликтов с переменными среды (хотя я, как известно, игнорировал это сам ...). – Fred
@Fred Когда я запускаю скрипт во второй раз, он работает так, как он должен работать. Он дает сообщение об ошибке и не запускает процесс. Я не понимаю вашу вторую часть, но то, что я имел в виду при убийстве $$, заключается в том, что я вручную ищу PID с командой «ps -ef», а затем убил его. Спасибо за ваш совет, я изменю его в своем исходном коде. Должен сказать, что я скопировал первую часть с PID-файлом с другого сообщения на форуме, но все равно остальное было довольно сложно, потому что в этом примере я не делал больше действий! – franktank