проблема подстановки команд bash с подоболочкой

Я пытался предотвратить одновременный запуск сценария более чем одним пользователем и не хотел использовать команды, доступные только в некоторых ОС или оболочках (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), я по-прежнему считаю, что переменная, которой присвоено значение подстановки команды, должна возвращать то же значение, что и сама команда...


person brierand    schedule 12.09.2015    source источник
comment
Большинство утилит с одинаковыми ограничениями используют одну и ту же стратегию: создать xxx.pid временный файл с PID текущего запущенного процесса. При запуске утилита проверяет наличие временного файла и останавливается, если он существует. Есть ли в вашем случае причина не использовать эту известную методику?   -  person Renaud Pacalet    schedule 12.09.2015
comment
Это не ошибка в том, что это принятое действие. Есть ряд других различий между ksh и bash, и да, разные результаты. Например, поведение цикла for на одном конце канала — в bash каждый конец выполняется в дочерних процессах. См. также stackoverflow.com/questions /14686872/   -  person cdarke    schedule 12.09.2015
comment
@cdarke: я согласен, что это не ошибка. Afaics, Posix не требует, чтобы подоболочка была отдельным процессом. Я думаю, что ваш связанный вопрос является ошибкой, но у меня есть небольшие сомнения, поэтому я не хочу применять Молоток; Я предлагаю вам либо проголосовать за закрытие, либо сделать свой комментарий ответом.   -  person rici    schedule 12.09.2015
comment
Да, в bash подоболочка получает свой собственный идентификатор процесса. В bash+linux запустите echo "$(ps f)" | less, а затем найдите ps f, и вы увидите все процессы, которые создает bash для запуска подстановки команд.   -  person John1024    schedule 12.09.2015
comment
ps -ef тоже нельзя назвать переносимым.   -  person tripleee    schedule 13.09.2015