1

Есть bash-скрипт script примерно следующего содержания:

cat file | xargs -t -P 1 -n1 ./script2

С запуском никаких проблем нет ./script, но вот как его остановить. Ctrl+C не подходит конечно, так как останавливать планирую по cron.
вариации на тему kill -15 script или kill -9 script не работают, так как в даном случае там и cat и xargs да еще и старт другого скрипта, в котором тоже целый набор стандартных команд.
Знаю что можно оформить в виде сервиса, так как это сделано в скриптах /etc/init.d/. Но для меня это слишком сложно, опыта не хватает, чтобы разобрать варианты, которые там есть. Нагугленные варианты на эту тему у меня почему-то не работают.

Помогите пожалуйста разобраться, как самым простым способ гарантированно остановить скрипт script и все дочерние (кажется так называется), которые он породил.

2 (01.11.2012 23:42:43 отредактировано -=Serj=-)

 Консоль:
$ cat script.sh

#!/bin/bash
time cat

 Консоль:
$ ./script.sh

Одновременно в другой консоли
 Консоль:
$ ps -A | grep script
19041 pts/6    00:00:00 script.sh
$ sudo killall script.sh

Скрипт останавливается. Ч. т. д. ?

Да, у меня Ubuntu.
Нет, не глючит.

3

Хотя не, cat продолжает висеть в процессах....

Да, у меня Ubuntu.
Нет, не глючит.

4

-=Serj=- пишет:

Хотя не, cat продолжает висеть в процессах....

да, в этом то и проблема.

5

Так вы попробуйте завершать cat, т.к. он является родительским процессом для других.

6 (02.11.2012 10:15:16 отредактировано Vascom)

На коленке можно сделать такой вариант:
Скрипт периодически проверяет наличие контрольного файла в /tmp. Если файла нет, то скрипт работает, если файл есть, то скрипт завершает работу.
Соответственно для остановки скрипта достаточно выполнить touch /tmp/control_file.

Я не утверждаю, что это оптимально, или правильно, но это должно сработать. А потом уже можно читать документацию и думать как это реализовать более изящно.

7

pitdron пишет:

Так вы попробуйте завершать cat, т.к. он является родительским процессом для других.

Так подход неправильный - другие скрипты могут тоже использовать cat и их нельзя обрывать.

8

Vascom пишет:

На коленке можно сделать такой вариант:
Скрипт периодически проверяет наличие контрольного файла в /tmp. Если файла нет, то скрипт работает, если файл есть, то скрипт завершает работу.
Соответственно для остановки скрипта достаточно выполнить touch /tmp/control_file.

Я не утверждаю, что это оптимально, или правильно, но это должно сработать. А потом уже можно читать документацию и думать как это реализовать более изящно.

Идея интересная, но сомнительно это все. Ну вот куда в моем примере всунуть проверку на существования тем-файла? Надо еще учитывать что тот же xargs может работать многопоточно - соответственно тем более непонятно куда проверку на существование файла всунуть...
Ну и да - неуниверсально смотрится.

Неужели нету какго-то элементарного метода убить bash-скрипт. Я думал это я чего-то не знаю, а сейчас начинаю понимать, что не все так просто.

9

valet пишет:

cat file | xargs -t -P 1 -n1 ./script2

Через screen сделай.

It is good day to die ...
MS Windows 10
Заметки о главном...

10

На самом деле всё просто. Только скрипт надо изначально писать правильно. Всякие внешние убивалки - это экстренная ситуация. Завершение скрипта должно быть предусмотрено в нём самом, иначе всегда будет криво и неоднозначно.

В bash достаточно механизмов для контроля работы скрипта, обеспечения его правильного и своевременного завершения.

11

pitdron пишет:

Так вы попробуйте завершать cat, т.к. он является родительским процессом для других.

не верно, cat ни чьим родителем не является. и не сработает, если xargs длительный...

Vascom пишет:

На коленке можно сделать такой вариант:Скрипт периодически проверяет наличие контрольного файла в /tmp. Если файла нет, то скрипт работает, если файл есть, то скрипт завершает работу.Соответственно для остановки скрипта достаточно выполнить touch /tmp/control_file.Я не утверждаю, что это оптимально, или правильно, но это должно сработать. А потом уже можно читать документацию и думать как это реализовать более изящно.

вариант хорош тем, что можно обойтись без убийств, но придётся вносить изменения в скрипт2 и не всегда получится, особенно, если script2 какую-то длительную операцию запускает...
в общем о том, что в script2 есть услышать было бы хорошо...

95% процентов проблем находятся между клавиатурой и стулом.

12

Fat-Zer пишет:

xargs длительный...

он очень длительный, практически бесконечный и выполняет однотипные операции. Поэтому появилась идея запускать и останавливать периодически по крону.

Fat-Zer пишет:

что в script2 есть услышать было бы хорошо...

ну я так примеру дал, не важно что там, вариантов много и они у меня используются, ну к примеру:
script2 такой:

#!/bin/bash

site=$1

sort -R index -o index
cat index|awk '{print rand()"\t"$0}'|sort|awk -F'\t' '{print $2}' > 1_"$site"
Fat-Zer пишет:

если script2 какую-то длительную операцию запускает...

опять таки по разному есть, например в этом варианте - да - операция длительная.

13

Vascom пишет:

На самом деле всё просто. Только скрипт надо изначально писать правильно. Всякие внешние убивалки - это экстренная ситуация. Завершение скрипта должно быть предусмотрено в нём самом, иначе всегда будет криво и неоднозначно.

А если он бесконечный или практически бесконечный, так как обрабатывается множество однотипных данных.

14

Vascom, дайте пожалуйста конкретный пример как вы остановите скрипт при проверки наличия файла. Я честно говоря вообще не знаю как можно выходить из скрипта пока он еще не завершился.

15

valet пишет:

Vascom, дайте пожалуйста конкретный пример как вы остановите скрипт при проверки наличия файла. Я честно говоря вообще не знаю как можно выходить из скрипта пока он еще не завершился.

я так понял это имелось в виду:

for ((i=0; i<100500; i++)); do
  sleep 1
  [ -f /path/to/stop/file ] && break
done

в порядке бреда: можно например запускать скрипт от отдельного пользователя и прибивать все его процессы...

valet пишет:

sort -R index -o index
cat index|awk '{print rand()"\t"$0}'|sort|awk -F'\t' '{print $2}' > 1_"$site"

а то, в каком порядке sort отсортировал вам не понравилось О_о ?

95% процентов проблем находятся между клавиатурой и стулом.

16 (02.11.2012 11:57:50 отредактировано Vascom)

valet пишет:

Vascom, дайте пожалуйста конкретный пример как вы остановите скрипт при проверки наличия файла. Я честно говоря вообще не знаю как можно выходить из скрипта пока он еще не завершился.

Примерно так

#!/bin/bash

function very_long_process() {
    sleep 30
    echo AA
    touch /tmp/control
}


# Start long process in background
very_long_process &

#Check control file
while [ ! -e "/tmp/control" ]
do  
    sleep 5
done
kill -9 "$!"

Роль длинного процесса выполняет команда sleep 30, то есть он будет идти 30 секунд и в результате выдаст на экран "AA". Запускаем его в бэкграунде, затем каждые 5 секунд проверяем появление контрольного файла. Если файл появился, то прерываем наш длинный процесс. Если же процесс выполнился нормально, то контрольный файл появится сам и мы снова выходим из скрипта.

$!  -  pid последнего процесса в фоновом режиме

17

Vascom пишет:

Роль длинного процесса выполняет команда sleep 30, то есть он будет идти 30 секунд и в результате выдаст на экран "AA". Запускаем его в бэкграунде, затем каждые 5 секунд проверяем появление контрольного файла. Если файл появился, то прерываем наш длинный процесс. Если же процесс выполнился нормально, то контрольный файл появится сам и мы снова выходим из скрипта.$!  -  pid последнего процесса в фоновом режиме

sleep будет работать до победного конца - все 30 секунд...

95% процентов проблем находятся между клавиатурой и стулом.

18 (02.11.2012 12:42:29 отредактировано Vascom)

Fat-Zer пишет:
Vascom пишет:

Роль длинного процесса выполняет команда sleep 30, то есть он будет идти 30 секунд и в результате выдаст на экран "AA". Запускаем его в бэкграунде, затем каждые 5 секунд проверяем появление контрольного файла. Если файл появился, то прерываем наш длинный процесс. Если же процесс выполнился нормально, то контрольный файл появится сам и мы снова выходим из скрипта.$!  -  pid последнего процесса в фоновом режиме

sleep будет работать до победного конца - все 30 секунд...

Не будет. Я проверил работу скрипта. "АА" не выдаётся в консоль.

19 (02.11.2012 12:59:49 отредактировано Fat-Zer)

Vascom пишет:

Не будет. Я проверил работу скрипта.

alexander@goblin /tmp $ cat ./script3.sh
#!/bin/bash

function very_long_process() {
        sleep 300
        echo AA
        touch "/tmp/control"
}


# Start long process in background
very_long_process &

#Check control file
while [ ! -e "/tmp/control" ]
do
        sleep 5
done
kill "$!"
rm "/tmp/control"
alexander@goblin /tmp $ ./script3.sh &
[1] 15047
alexander@goblin /tmp $ ps aux | grep sleep && touch /tmp/control && ps aux | grep sleep && sleep 5 && ps aux | grep sleep && sleep 5 && ps aux | grep sleep1000     15050  0.0  0.0   7724   624 pts/9    S    12:54   0:00 sleep 300
1000     15055  0.0  0.0   7724   624 pts/9    S    12:55   0:00 sleep 5
1000     15057  0.0  0.0  10300   916 pts/9    S+   12:55   0:00 grep --colour=auto sleep
1000     15050  0.0  0.0   7724   624 pts/9    S    12:54   0:00 sleep 300
1000     15055  0.0  0.0   7724   624 pts/9    S    12:55   0:00 sleep 5
1000     15060  0.0  0.0  10300   916 pts/9    S+   12:55   0:00 grep --colour=auto sleep
./script3.sh: line 19: 15048 Завершено      very_long_process
[1]+  Done                    ./script3.sh
1000     15050  0.0  0.0   7724   624 pts/9    S    12:54   0:00 sleep 300
1000     15064  0.0  0.0  10300   916 pts/9    S+   12:55   0:00 grep --colour=auto sleep
1000     15050  0.0  0.0   7724   624 pts/9    S    12:54   0:00 sleep 300
1000     15067  0.0  0.0  10300   916 pts/9    S+   12:55   0:00 grep --colour=auto sleep
Vascom пишет:

"АА" не выдаётся в консоль.

не выдаётся, но sleep работает

ЗЫ: можно ещё нашаманить что-нить с перехватом сигналов...

95% процентов проблем находятся между клавиатурой и стулом.

20

Нда, может я и не прав. Но общий принцип понятен.
Может не надо в функцию это оформлять, а саму команду в бэкграунд пустить и её pid запомнить в переменную.

21

Fat-Zer пишет:

я так понял это имелось в виду:

Нет, конкретнее в моем примере куда впихнуть - у меня же вообще одна команда:

cat file | xargs -t -P 1 -n1 ./script2

И куда тут внедрить проверку?

Fat-Zer пишет:

а то, в каком порядке sort отсортировал вам не понравилось О_о ?

Да ab не понравилось, sort -R не отрабатывает правильно с кириллицей, там надо закомментировать. А конструкция ниже работает.

Какие-то сложные танцы с бубном получаются - неужели все так сложно и нельзя никак проще.

22

Назначить через алиас в баше короткую команду на скрипт который прибьет другой скрипт, идентификатором будет служить например pid в файле.

XMPP: mogul82@jabber.ru Фанбой AMD

23

mogul82 пишет:

Назначить через алиас в баше короткую команду на скрипт который прибьет другой скрипт, идентификатором будет служить например pid в файле.

А каким образом он собственно его прибьет, В этом то и вопрос что прибить скрипт сложно. Ну по крайней мере я до сих пор е вижу решения.

24 (05.11.2012 17:02:32 отредактировано yars)

PID у любого процесса есть же.

# pidof bash
2522

Далее, killall 2522 от рута ab

Истинный hotplug - это обычная электрическая розетка: воткнул - работает, и никаких драйверов.
Slackware64-current/Xfce/Lenovo G580

25

на лоре была идея использовать cgroups. ИМХО это будет Ъ.
сам попробовать не могу т.к. у меня они из ядра выпилены...
ещё вариант, обходить самому всех детей и убивать, но это не хорошо т.к. очень плохо т.к. черевато состоянием гонки...

yars пишет:

Далее, killall 2522 от рута

бред какой-то... не?

95% процентов проблем находятся между клавиатурой и стулом.

26 (05.11.2012 17:37:12 отредактировано yars)

Fat-Zer пишет:

бред какой-то... не?

Не, это всего лишь пример, на самом деле, так делать я и не собирался. А в чем проблема-то? У скрипта же тоже PID есть, что мешает его прибить?
Или я чего-то не понимаю?

Истинный hotplug - это обычная электрическая розетка: воткнул - работает, и никаких драйверов.
Slackware64-current/Xfce/Lenovo G580

27

yars пишет:

Не, это всего лишь пример, на самом деле, так делать я и не собирался. А в чем проблема-то? У скрипта же тоже PID есть, что мешает его прибить?

в том что killall убивает по имени...
а вообще тут ИМХО задача равносильная «убить процесс и всех потомков»

95% процентов проблем находятся между клавиатурой и стулом.

28

yars пишет:

Не, это всего лишь пример, на самом деле, так делать я и не собирался. А в чем проблема-то? У скрипта же тоже PID есть, что мешает его прибить?
Или я чего-то не понимаю?

Прочитайте топик ab - это не помогает. Это не убивает те процессы, которые запущены этим скриптом, это убивает только сам скрипт, а что толку то...

29

Fat-Zer пишет:

а вообще тут ИМХО задача равносильная «убить процесс и всех потомков»

да, именно, в этом то и вся соль.

30

/рукалицо

всё намного проще:

man kill пишет:

The default signal for kill is TERM. Use -l or -L to list available signals.  Particularly useful signals include HUP, INT, KILL, STOP, CONT, and 0.  Alternate signals may be specified in three ways: -9 -SIGKILL -KILL.  Negative PID values may be used to choose whole process groups; see the PGID column in ps command output. A PID of -1 is special; it indicates all processes except the kill process itself and init.

alexander@goblin /tmp $ cat script1.sh
#!/bin/bash
sleep 300
alexander@goblin /tmp $ ./script1.sh & echo $! >/tmp/pid
[1] 20998
alexander@goblin /tmp $ ps aux | grep sleep
1000     20999  0.0  0.0   7724   624 pts/5    S    17:48   0:00 sleep 300
1000     21001  0.0  0.0  10300   916 pts/5    S+   17:49   0:00 grep --colour=auto sleep
alexander@goblin /tmp $ kill -9 -$(cat /tmp/pid)
[1]+  Убито              ./script1.sh
alexander@goblin /tmp $ ps aux | grep sleep
1000     21004  0.0  0.0  10300   916 pts/5    S+   17:49   0:00 grep --colour=auto sleep
95% процентов проблем находятся между клавиатурой и стулом.