Ctrl-C с двумя одновременными командами в ударе

Я нашел очень полезный ответ на:

https://wiki.archlinux.org/index.php/VirtualBox#Mounting_. vdi_Images

Подсказка должна использовать offset опция ext4 монтируется (чтобы быть более конкретным, в задних сценах это использует offset как опция для устройства закольцовывания losetup)

Это о

  • взятие offData информация из изображения VDI
  • добавление магического числа 32256
  • и использование результата как смещение

Вот мой способ автоматизировать его:

VDIfile=VirtData.vdi
mountingpoint=/mnt/VDI
offData=$( VBoxManage internalcommands dumphdinfo "$VDIfile" |grep offData | sed 's:.*offData=\([0-9]*\).*:\1:' )
offset=$(( $offData + 32256 ))
mount -t ext4 -o rw,noatime,noexec,loop,offset="$offset" "$VDIfile" "$mountingpoint"

Для /etc/fstab Вы хотели бы добавлять: (123456789 считается ранее смещение),

/path/VirtData.vdi      /mnt/VDI        ext4 rw,noatime,noexec,loop,offset=123456789,user,noauto

Конечно, rw может быть изменен на ro или Вам, возможно, не понадобилось бы noatime или noexec - taylor их к Вашим потребностям

Btw., если Ваш путь содержит пробелы, существует прием изменения spaces в \040 (источник: https://wiki.archlinux.org/index.php/Fstab)

15
25.08.2016, 14:04
4 ответа

Если Вы вводите

command 1 & command 2

это равно

command 1 &
command 2

т.е. это выполнит первую команду в фоне и затем выполняет вторую команду на переднем плане. Особенно это означает, что Ваш echo "done" печатается после command 2 законченный, даже если command 1 все еще работает.

Вы, вероятно, хотите

command 1 &
command 2 &
wait
echo "done"

Это будет выполнять обе команды в фоне и ожидать обоих для завершения.


При нажатии CTRL-C, это только отправит сигнал SIGINT в приоритетный процесс, т.е. command 2 в Вашей версии или wait в моей версии.

Я предложил бы поставить капкан как это:

#!/bin/bash

trap killgroup SIGINT

killgroup(){
  echo killing...
  kill 0
}

loop(){
  echo $1
  sleep $1
  loop $1
}

loop 1 &
loop 2 &
wait

С прерыванием сигнал SIGINT, произведенный CTRL-C, захватывается и заменяется killgroup функция, которая уничтожает все те процессы.

17
27.01.2020, 19:49
  • 1
    Спасибо за Ваш ответ! У меня действительно однако есть последующий вопрос. У меня теперь есть следующий сценарий: захватите killgroup SIGINT killgroup () {эхо, уничтожающее..., уничтожает 0} command001 command1 и command2, я опустил команду ожидания, потому что сценарию позволяют продолжиться, когда command2 закончен. Однако кажется, что команда 1 уже запускается, когда я запускаю скрипт. Я могу зафиксировать это? Спасибо –  maero21 04.01.2014, 00:35
  • 2
    command1 запускается непосредственно после того, как command001 закончен. можно использовать set -x в начале Вашего сценария для печати команд, которые выполняются. –  michas 04.01.2014, 02:03

При помещении команды в фон из сценария PID не отображен на экране. Можно использовать встроенную переменную $! который хранит PID последнего процесса, таким образом, можно получить PID command1.

command1 &
echo $!

повторил бы PID command1.

Bash также обеспечивает прерывание, встроенное, который можно использовать для регистрации последовательности команд для выполнения, когда конкретные сигналы получены. Можно использовать это, чтобы поймать SIGINT и уничтожить command1 прежде, чем выйти из основного сценария, например.

#!/bin/bash

onINT() {
echo "Killing command1 $command1PID too"
kill -INT "$command1PID"
exit
}

trap "onINT" SIGINT
command1 &
command1PID="$!"
comamnd2
echo Done

Теперь, пока команда 2 работает, совершая нападки Ctrl C заставит и command1 и command2 быть отправленным SIGINT.

6
27.01.2020, 19:49
  • 1
    Можно также использовать %n синтаксис для уничтожения определенных фоновых заданий в этой оболочке. Обычно Вы выходите kill %1 уничтожить последнее и единственный фоновый процесс. С большим количеством фоновых процессов использовать jobs видеть список сначала. –  9000 01.01.2014, 17:29
  • 2
    @9000: Да, но OP выполняет их команды в сценарии (./execute.sh), настолько добирающиеся задания для работы намного более проблематично, конечно? –   01.01.2014, 17:33
  • 3
    @lain: конечно. Я упустил суть о выполнении из сценария. –  9000 01.01.2014, 18:50

Более новые версии Параллели GNU сделают то, что Вы хотите:

parallel ::: "command 1" "command 2"
echo "done"

Или если command остается тем же:

parallel command ::: 1 2
echo done

Посмотрите вводное видео для краткого введения: https://www.youtube.com/playlist? list=PL284C9FF2488BC6D1

Обход через учебное руководство (человек parallel_tutorial). Вы командная строка с любовью Вы для него.

5
27.01.2020, 19:49

Ctrl + C отправляет сигнал SIGINT в Ваш передний процесс, который является command2. command1 выполняется в фоне, поэтому не затронутом входным потоком.

Когда Вы вводите command1 &, удар должен дать Вам PID процесса, что-то как [1234]. Для уничтожения этого процесса можно использовать kill 1234. Теперь, если у Вас есть PIDs обоих command1 и command2 (взгляните на ps -ef), можно использовать kill завершать их всех:

kill pid1 pid2 pid3 ...

Немного приема должно было бы выполнить обе команды в фоне, с:

command1 & command2 &

Bash даст Вам обоим PIDs, готовый быть уничтоженным. Другой прием должен был бы возвратить command1 на переднем плане, после того как Вы уничтожили command2 :

command1 & command2
# Hit Ctrl+C : command2 terminates.

fg # Bring back command1 to foreground.
# Hit Ctrl+C again, command1 terminates.

Больше информации, доступной здесь: http://linuxg.net/how-to-manage-background-and-foreground-processes/

1
27.01.2020, 19:49

Теги

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