Как остановиться, цикл колотят сценарий в терминале?

В пустом каталоге:

% stat .
  File: `.'
  Size: 6               Blocks: 0          IO Block: 4096   directory
Device: fe04h/65028d    Inode: 537317737   Links: 2
Access: (0750/drwxr-x---)  Uid: ( 1000/stribika)   Gid: (  100/   users)
Access: 2011-02-22 08:47:20.935036074 +0100
Modify: 2011-02-22 08:47:20.935036074 +0100
Change: 2011-02-22 08:47:20.935036074 +0100
 Birth: -
% mkdir foo
% stat .
  File: `.'
  Size: 16              Blocks: 0          IO Block: 4096   directory
Device: fe04h/65028d    Inode: 537317737   Links: 3
Access: (0750/drwxr-x---)  Uid: ( 1000/stribika)   Gid: (  100/   users)
Access: 2011-02-22 08:47:20.935036074 +0100
Modify: 2011-02-22 08:47:57.465036072 +0100
Change: 2011-02-22 08:47:57.465036072 +0100
 Birth: -
% stat foo
  File: `foo'
  Size: 6               Blocks: 0          IO Block: 4096   directory
Device: fe04h/65028d    Inode: 509269      Links: 2
Access: (0750/drwxr-x---)  Uid: ( 1000/stribika)   Gid: (  100/   users)
Access: 2011-02-22 08:47:57.465036072 +0100
Modify: 2011-02-22 08:47:57.465036072 +0100
Change: 2011-02-22 08:47:57.465036072 +0100
 Birth: -

Поскольку Вы видите, что существует 2 ссылки на пустой каталог. Когда я создаю новый в нем, число каналов увеличивается до 3. Additionaly там являются 2 ссылками на новый каталог. Общее количество является 3 новыми ссылками.

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

56
17.09.2012, 21:14
10 ответов

Программа sl намеренно игнорирует SIGINT, который является тем, что отправляется, когда Вы нажимаете Ctrl+C. Так, во-первых, необходимо будет сказать sl не проигнорировать SIGINT путем добавления -e аргумент.

При попытке этого Вы заметите, что можно остановить каждого человека sl, но они все еще повторяются. Необходимо сказать bash выходить после SIGINT также. Можно сделать это путем помещения a trap "exit" INT перед циклом.

#!/bin/bash
trap "exit" INT
while :
do
    sl -e
done
69
27.01.2020, 19:33
  • 1
    , который мне не установили его для проверки, но Вы могли бы также смочь уничтожить его с SIGQUIT от Ctrl-\ –  derobert 17.09.2012, 20:36
  1. пресса Ctrl-Z приостановить сценарий
  2. kill %%

%% говорит встроенный удар kill то, что Вы хотите отправить сигнал (SIGTERM по умолчанию) к последний раз приостановленному фоновому заданию в текущей оболочке, не к идентификатору процесса.

Можно также указать задания числом или по имени. например, когда Вы приостанавливаете задание с ^Z, удар скажет Вам, как что его число задания с чем-то [n]+ Stopped, где n в квадратных скобках число задания.

Для большего количества информации об управлении заданиями и об уничтожении заданий, выполненных help jobs, help fg, help bg, и help kill в ударе и поиске JOB CONTROL (все заглавные буквы) или jobspec в странице справочника удара.

например.

$ ./killme.sh 
./killme.sh: line 4: sl: command not found
./killme.sh: line 4: sl: command not found
./killme.sh: line 4: sl: command not found
./killme.sh: line 4: sl: command not found
./killme.sh: line 4: sl: command not found
...
...
...
./killme.sh: line 4: sl: command not found
^Z
[1]+  Stopped                 ./killme.sh
$ kill %%
$ 
[1]+  Terminated              ./killme.sh

В этом примере число задания равнялось 1, таким образом, kill %1 работал бы то же как kill %%

(ПРИМЕЧАНИЕ: Я не имею sl установленный, таким образом, вывод является просто "командой, не найденной". в Вашем случае Вы доберетесь, любой вывод sl производит. это не важно - ^Z приостановите и kill %% будет работать то же),

123
27.01.2020, 19:33
  • 1
    Другой хороший ответ! –  Yinyanghu 18.09.2012, 05:25
  • 2
    BTW, для того, чтобы быстро выполнить циклы как это, ^Z может быть более надежным способом уничтожить процесс, чем ^C. ^C будет отправлен в программу (sl) быть выполненным в цикле, но сценарий будет продолжать бежать... и запускать другого sl. При нажатии ^C несколько раз действительно быстро можно добраться для уничтожения обоих sl и сценарий (если ни один из них не захватывает SIGINT). ^Z приостановит сценарий почти сразу (сразу, если Вы не будете считать буферизованный вывод, который все еще печатается к Вашему терминалу), таким образом, можно уничтожить его с kill %% –  cas 18.09.2012, 05:48
  • 3
    TDWTF Точно! Я должен сказать"sl забавная программа". На этот раз, это забава я снова! _ –  Yinyanghu 18.09.2012, 06:07
  • 4
    Только ответ, который, кажется, работает также, когда цикл не называют из сценария, но из командной строки непосредственно. –  Skippy le Grand Gourou 03.08.2014, 13:25
  • 5
    @DrewChapin, который я не могу помнить, когда/где я узнал об этом - просто что-то, которое я знал "с тех пор навсегда". В странице справочника удара (поиск jobspec) говорится: The symbols %% and %+ refer to the shell's notion of the current job, which is the last job stopped while it was in the foreground or started in the background. The previous job may be referenced using %-. If there is only a single job, %+ and %- can both be used to refer to that job –  cas 18.02.2018, 08:23

Можно завершить тот сценарий путем нажатия Ctrl+C от терминала, где Вы запустили этот сценарий. Конечно, этот сценарий должен работать на переднем плане, таким образом, Вы можете остановить его Ctrl+C.

Или можно найти PID (идентификатор Процесса) того сценария в другом открытом терминале:

ps -ef | grep <name_of_the_script>
kill -9 <pid_of_your_running_script>

Оба пути должны добиться цели Ваш, просят.

3
27.01.2020, 19:33
  • 1
    Это не может быть завершено Ctrl+C от терминала. Таким образом, я должен уничтожить его PS или вершиной. Я просто хочу знать, как уничтожить его непосредственно! –  Yinyanghu 17.09.2012, 19:15
while [ true ] 
do

  #check if script is running
  ps | grep script_name.sh | grep -v grep >/dev/null 2>&1

  if [ "$!" != "0" ] ; then
    break
  else

    kill -9 ` ps -ef | grep script_name.sh | cut -d "a" -f 1` 
    echo "kill -9 `get script PID`"

  fi

done

это должно помочь.

-1
27.01.2020, 19:33
  • 1
    Почему Вы думаете, что PID последней фоновой команды когда-либо будет 0? –  manatwork 08.08.2013, 16:18

Вы можете убить идентификатор pid оболочки (bash).
Я просто попробовал, и все работает.
Потому что я не вижу процесс из ps -ef (задание, которое мы запускаем в сценарии цикла).

1
27.01.2020, 19:33

Использование SET для выхода из отказа.

#!/bin/bash
set -e
while :
do
    sl
done
-1
27.01.2020, 19:33

Убийство - это ужасно, потому что вы никогда не узнаете, должен ли скрипт выполняться дважды. И код выхода неправильный.

while [ something ]; do

 if [ somethingelse ]; then
   echo shut down script with exit code 0
   exit 0
 fi
done

echo something else not happend
exit 2 # Return val important for example for monitoring

Не работает. Решение = использовать perl. while opens own bash

-1
27.01.2020, 19:33

Как отметил @ Shadur, эта проблема может быть связана с вашим интернет-провайдером (или сетью, в которой установлен сервер). При наличии ограничений безопасности для порта SMTP (номер порта 25) серверы MX не могут получить доступ через этот порт.

Вместо этого можно использовать SMTP через порт SSL (ssmtp, номер порта 465). Для этого отредактируйте файл /etc/postfix/master.cf , прокомментируйте smtp-строку и добавьте вместо нее ssmtp-строку:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
#smtp      inet  n       -       -       -       -       smtpd
ssmtp      inet  n       -       -       -       -       smtpd

Чтобы проверить, распознана ли эта запись с таким именем на вашем компьютере, можно выполнить следующие действия:

$>cat /etc/services | grep smtp
smtp        25/tcp      mail
ssmtp       465/tcp     smtps       # SMTP over SSL
-121--42043-

Если оболочка входа даже не запускается, вход в систему невозможен. Клиент отправляет последовательность на сервер, и для интерпретации последовательности требуется оболочка входа пользователя на сервере. Клиент не имеет пути указывать серверу «выполнить другую команду».

Это механизм безопасности: если оболочка пользователя ограничена тем, что он может сделать, то пользователь не может сделать ничего, что не позволяет.

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

Некоторые советы:

  • При обслуживании всегда держите корневую оболочку открытой и не закрывайте ее, пока не протестируете, что все работает.
  • Установите статически связанную оболочку на учетную запись с правами sudoer. Я не вижу какой-либо предварительной упаковки от Arch. Debian имеет несколько ; можно просто скопировать исполняемый файл и добавить его в /etc/shells .
  • Убедитесь, что у вас есть способ укорениться, даже если некоторые вещи сломаны; Набор оболочку корня в bash-static или sash или набор учетную запись toor (альтернативный способ входа корня в систему). Имейте в виду, что sudo тоже может сломаться; возможно, вы захотите иметь экстренный пароль на аккаунте, который случайно создан (уникальный и не заучен) и записан на бумажке, которую вы храните в сейфе.
-121--114075-

Самым простым способом является выдача сигнала QUIT , который обычно подключается к Control-Backslash .

Когда вы увидите поезд, нажмите Control -\

4
27.01.2020, 19:33

Если вы хотите, чтобы ctrl + c остановил цикл, но не завершил скрипт, вы можете поместить || break после любой выполняемой команды. Пока программа, которую вы запускаете, завершается нажатием ctrl + c, это отлично работает.

#!/bin/bash
while :
do
    # ctrl+c terminates sl, but not the shell script
    sl -e || break
done

Если вы находитесь во вложенном цикле, вы можете использовать «break 2», чтобы выйти из двух уровней и т. Д.

7
27.01.2020, 19:33

Другой способ завершить весь сценарий - запустить команду sl в фоновом режиме, а затем перехватить сигнал INT для убить всю группу процессов сценария с помощью сигнала HUP .

#!/bin/bash

trap 'trap - INT; kill -s HUP -- -$$' INT
#trap 'trap - INT; kill -s HUP 0' INT

while :
do
   sl & wait
done
0
27.01.2020, 19:33

Теги

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