Я пытался предотвратить одновременный запуск сценария более чем одним пользователем и не хотел использовать команды, доступные только в некоторых ОС или оболочках (pgrep, pidof, ...), и столкнулся с проблемой, которой я не занимаюсь. понятно баг это или нет...
Пожалуйста, не обращайте внимания на особенности, которые я использовал в своем скрипте: проблема связана с подстановкой команд в bash при использовании ps.
Когда я запускаю следующее (обратите внимание на shebang в ksh):
#!/bin/ksh
CMD=`basename $0`
echo $CMD
ps -ef | grep "$CMD"
ps -ef | grep "$CMD" | wc -l
RUNS=`ps -ef | grep "$CMD" | wc -l`
echo $RUNS
if [ $RUNS -gt 2 ]; then
echo The script is currently being run by another user.
#exit 1
fi
RUNS=`ps -ef | grep "$CMD"`
echo "$RUNS"
RUNS=`echo "$RUNS" | wc -l`
echo $RUNS
if [ $RUNS -gt 2 ]; then
echo The script is currently being run by another user.
#exit 1
fi
ps -ef | grep "$CMD" | wc -l > lock
RUNS=`cat lock`
echo $RUNS
if [ $RUNS -gt 2 ]; then
echo The script is currently being run by another user.
exit 1
fi
Я получаю этот правильный вывод:
testksh.sh7
abriere 19126 5669 0 14:15 pts/21 00:00:00 /bin/ksh ./testksh.sh7
abriere 19129 19126 0 14:15 pts/21 00:00:00 grep testksh.sh7
2
2
abriere 19126 5669 0 14:15 pts/21 00:00:00 /bin/ksh ./testksh.sh7
abriere 19137 19126 0 14:15 pts/21 00:00:00 grep testksh.sh7
2
2
Я получаю это после замены shebang на bash и соответствующего переименования скрипта:
testbash.sh7
abriere 5631 5669 0 14:12 pts/21 00:00:00 /bin/bash ./testbash.sh7
abriere 5634 5631 0 14:12 pts/21 00:00:00 grep testbash.sh7
2
3
The script is currently being run by another user.
abriere 5631 5669 0 14:12 pts/21 00:00:00 /bin/bash ./testbash.sh7
abriere 5643 5631 0 14:12 pts/21 00:00:00 /bin/bash ./testbash.sh7
abriere 5645 5643 0 14:12 pts/21 00:00:00 grep testbash.sh7
3
The script is currently being run by another user.
2
Обратите внимание на дополнительную строку в выводе ps.
Следующая строка в bash:
RUNS=`ps -ef | grep "$CMD" | wc -l`
не возвращает то же значение, что и:
ps -ef | grep "$CMD" | wc -l
Кш не имеет этой проблемы.
Как видите, есть обходные пути: я использую один в последнем разделе своего скрипта.
Я запускал сценарии в Linux, AIX и SunOS, и они давали мне те же результаты; только Cygwin не сделал, но команда ps не возвращает скрипт ни в одной оболочке.
Это ошибка? Даже если bash запускает подстановку команд внутри подоболочки (см. вопрос 21331042), я по-прежнему считаю, что переменная, которой присвоено значение подстановки команды, должна возвращать то же значение, что и сама команда...
xxx.pid
временный файл с PID текущего запущенного процесса. При запуске утилита проверяет наличие временного файла и останавливается, если он существует. Есть ли в вашем случае причина не использовать эту известную методику? - person Renaud Pacalet   schedule 12.09.2015for
на одном конце канала — в bash каждый конец выполняется в дочерних процессах. См. также stackoverflow.com/questions /14686872/ - person cdarke   schedule 12.09.2015echo "$(ps f)" | less
, а затем найдитеps f
, и вы увидите все процессы, которые создает bash для запуска подстановки команд. - person John1024   schedule 12.09.2015ps -ef
тоже нельзя назвать переносимым. - person tripleee   schedule 13.09.2015