Уничтожение сценария оболочки, работающего в фоне

Если бы это был Linux, то команда, которую Вы использовали бы, была бы:

ip route add 192.168.0.0/16 via 10.8.0.7

Это требует, чтобы ip_forwarding был включен на ПК (предположение, что это - поле Linux, я уверен, что существует подобное понятие в других Ose). Я не уверен, доступна ли "IP" команда на Mac.

12
14.04.2019, 11:34
4 ответа

Разница, скорее всего, в переменных средах и текущем рабочем каталоге. Сервис начинает скрипт из / и с чистой средой. Таким образом, вам может потребоваться изучить вашу среду и текущий рабочий каталог (с помощью экспорта , PWD или SET командам) и добавить отсутствующие предварительные условия в ваш скрипт Отказ

-121--217608-

для улучшения, использования Killiall , а также объединить команды:

ps -aux | grep script_name
killall script_name inotifywait

или сделать все в одной строке:

killall `ps -aux | grep script_name | grep -v grep | awk '{ print $1 }'` && killall inotifywait
5
27.01.2020, 19:56

Перечислите фоновые задания, используя

# jobs

Then choose the prior number of job and run

example

# fg 1 

enter image description here

will bring outground.

Затем убейте его, используя CTRL+C или более простой способ найти PID скрипта, используя

ps -aux | grep script_name

enter image description here

Затем убейте, используя pid

sudo kill -9 pid_number_here
3
27.01.2020, 19:56

Файл конфигурации - /etc/sysconfig/network-scripts/ifcfg-eth0 , а не /etc/sysconfig/network-scripts/ifcfg-etho . Аналогично, имя устройства в файле конфигурации должно быть eth0 , а не etho .

В файле конфигурации слова слева от знаков равенства должны быть ALL _ CAPS . Перед или после каждого знака равенства не должно быть места.

Предполагается, что драйвер USB Ethernet работает, что далеко не точно. Если да, то при запуске /sbin/ifconfig следует видеть это сетевое устройство. Если он указан в списке, но не назван eth0 , то необходимо переименовать и соответствующим образом скорректировать файл конфигурации. Если вы не видите никакого сетевого устройства, кроме интерфейса lo loopback, то... у вас гораздо более сложная проблема.

-121--196217-

Невозможно выполнить /bin/bash в своей учетной записи, что, скорее всего, связано с подключением файловой системы с параметром noexec , а также с nosuid . Вы можете проверить этот запуск с помощью команды mount, так как это покажет параметры монтирования, и вам может понадобиться перемонтировать файловую систему с другими параметрами.

-121--51804-

Можно использовать ps + grep или pgrep для получения имени процесса / pid ; позже используйте killall / pkill для уничтожения имени процесса или kill для уничтожения pid. Все следующее должно сработать.

killall $(ps aux | grep script_name | grep -v grep | awk '{ print $1 }') && killall inotifywait
(ps -ef | grep script_name | grep -v grep | awk '{ print $1 }' | xargs killall) && killall inotifywait
(ps -ef | grep script_name | grep -v grep | awk '{ print $2 }' | xargs kill) && killall inotifywait
(pgrep -x script_name | xargs kill) && pkill -x inotifywait
pkill -x script_name && pkill -x inotifywait

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

pkill / pgrep соответствует шаблону , а не точному имени , поэтому является более опасным; здесь -x добавляется в соответствии с точным именем.

Также при использовании pgrep / pkill может потребоваться

  • -f для соответствия полной командной строке (например, ps aux does)
  • -a для печати имени процесса.
2
27.01.2020, 19:56

Как вы, вероятно, можете сказать, есть много способов сделать это.

Что касается вашей "UPDATE #2" -- в общем случае, завершение любого процесса в иерархии родитель-ребенок, как правило, завершает все связанные с ним процессы. Но есть много исключений. В идеале, вы хотите завершить последний "дочерний" процесс в дереве процессов, тогда родитель(и) этого дочернего процесса должен выйти из процесса, если у него нет других задач для выполнения. Но если вы убьете родителя, сигнал должен быть передан дочерним процессам, когда родитель умирает, и дочерние процессы также должны выйти - но бывают случаи, когда дочерние процессы могут игнорировать сигнал (через ловушки или подобные механизмы) и могут продолжать запускать завещание, унаследованное процессом 'init' (или подобным образом.) Но этот предмет поведения процесса может усложниться, и я просто оставлю его там....

Один из методов, который мне нравится, если я не хочу использовать контрольный скрипт (описанный далее) - это использование утилиты 'screen' для запуска и управления процессом. Команда 'screen' полна возможностей и может занять некоторое время. Я бы рекомендовал вам прочитать man-страницу 'screen' для полного объяснения. Быстрым примером запуска процесса в фоновом режиме будет команда:

screen -d -m /path/to/program

Это запустит "/path/to/program" внутри сеанса "screen".

Вы можете увидеть свой запущенный сеанс с помощью команды:

screen -ls

И в любое время Вы можете снова подключиться к запущенной программе с помощью команды:

screen -r

А затем просто прервать её с помощью ^C или ещё чего-нибудь.

Помимо того, что вы можете переподключиться и отсоединиться от процесса по желанию, "screen" перехватит любой stdout(), который может произвести ваша программа.


Но моим личным предпочтением в этих вопросах является наличие управляющей программы, которая управляет запуском и остановкой процесса. Это может быть несколько сложно и требует некоторых спорно сложных сценариев. И как любой сценарий, есть десятки хороших способов сделать это. Я включил пример bash метода, который я обычно использую для запуска и остановки приложений. Если ваша задача проста, вы можете вставить его непосредственно в управляющий скрипт -- или заставить этот управляющий скрипт вызвать другую внешнюю программу. Обратите внимание, что этот пример ни в коем случае не является исчерпывающим с точки зрения управления процессом. Я пропустил возможность таких сценариев: Убедитесь, что сценарий еще не запущен, когда вы используете опцию "start", подтверждая, что запущенный PID на самом деле является процессом, который вы запустили (например, ваш сценарий не умер и другой процесс был запущен с использованием того же самого PID), и подтверждая, что сценарий на самом деле ответил (вышел) при первом запросе "kill". Выполнение всех этих проверок может усложниться, и я не хотел делать пример слишком длинным и сложным. Возможно, вы захотите модифицировать пример, чтобы попрактиковаться в написании сценария оболочки.

Сохраните следующий код в файл под названием "programctl", сделайте его исполняемым с помощью команды:

chmod 755 programctl

Затем отредактируйте файл и добавьте свой код/скрипт в секцию регистра, которая начинается с "myscript".

После того, как все будет готово, предполагая, что "programctl" находится в текущем каталоге, вы можете запустить свою программу с:

./programctl start

И остановить ее с:

./programctl stop

Cheers.

#!/bin/bash
# Description:  A wrapper script used to stop/start another script.

#--------------------------------------
# Define Global Environment Settings:
#--------------------------------------

# Name and location of a persistent PID file

PIDFILE="/tmp/tmpfile-$LOGNAME.txt"

#--------------------------------------
# Check command line option and run...
# Note that "myscript" should not
# provided by the user.
#--------------------------------------

case $1
in
    myscript)
        # This is where your script would go.
        # If this is a routine 'bash' shell script, you can enter
        # the script below as illustrated in the example.  
        # Or you could simply provide the path and parameters
        # to another script such as /dir/name/command -options

        # Example of an embedded script:

        while true
        do
            # do something over and over...
            sleep 1
        done

        # Example of an external script:

        /usr/local/bin/longrun -x
    ;;

    start)
        # Start your script in the background.
        # (Note that this is a recursive call to the wrapper
        #  itself that effectively runs your script located above.)
        $0 myscript &

        # Save the backgound job process number into a file.
        jobs -p > $PIDFILE

        # Disconnect the job from this shell.
        # (Note that 'disown' command is only in the 'bash' shell.)
        disown %1

        # Print a message indicating the script has been started
        echo "Script has been started..."
    ;;

    stop)
        # Read the process number into the variable called PID
        read PID < $PIDFILE

        # Remove the PIDFILE
        rm -f $PIDFILE

        # Send a 'terminate' signal to process
        kill $PID

        # Print a message indicating the script has been stopped
        echo "Script has been stopped..."
    ;;

    *)
        # Print a "usage" message in case no arguments are supplied
        echo "Usage: $0 start | stop"
    ;;
esac
1
27.01.2020, 19:56

Теги

Похожие вопросы