Как приостановить и принести фоновый процесс к переднему плану

Можно работать student_head когда в папке для автоматического добавления имени папки как заголовка в записываемые файлы в нем и его подкаталогах:

student_head_action() {
    # We can't use parameter expansion on $PWD because of recursion
    local _dirname="${1%/*}"
    _dirname="${_dirname##*/}"

    [[ -d $1 ]] && return 0
    if ! [[ -w $1 && -f $1 ]]; then
        printf '%s\n' "$1 does not exist or is not writeable, skipping"
        return 1
    fi
    bash -c "ed -s {} <<< $'0a\n'"# Student: ${_dirname}"$'\n.\n,s/\r//g\nw'"
}

student_head() {

    local _file
    if (( $# )); then
        for _file; do
            student_head_action "${_file}" || _retval=1
        done
    else
        if shopt -s globstar > /dev/null 2>&1; then
            for _file in **/*; do
                student_head_action "${_file}" || _retval=1
            done
           shopt -u globstar
        else
            printf '%s\n' 'Globstar isn't available, attempting to use GNU find...'
            find . -type f -writable -exec bash -c '
                _dirname="${1%/*}\
                _dirname="${_dirname##*/}\
                ed -s "$1" <<< '"$'0a\n'"'"# Student: ${_dirname}"'"$'\n.\n,s/\r//g\nw'" {} \;
        fi                
    fi

    return "${_retval-0}"
}

Вставьте эти функции Ваш ~/.bashrc если Вы хотите student_head всегда быть доступным для Вашего пользователя при использовании bash.

student_head может быть назван двумя способами:

  1. Без аргументов. В этом режиме всем записываемым файлам в текущем каталоге и его подкаталогах предварительно ожидали заголовок.
  2. С именами файлов как аргументы. В этом режиме только файлам, перечисленным в аргументах, предварительно ожидали заголовок.

Если файл в аргументах не существует, student_head возвращает статус выхода 1.

Нужно упомянуть, что этот сценарий использует globstar, который требует bash>=4.0.

176
09.08.2012, 04:12
5 ответов

Как Tim сказал, ввести fg возвращать последний процесс переднему плану.

Если у Вас есть больше чем один процесс, работающий в фоновом режиме, сделайте это:

$ jobs
[1]   Stopped                 vim
[2]-  Stopped                 bash
[3]+  Stopped                 vim 23

fg %3 принести vim 23 обработайте назад к переднему плану.

Для приостановки процесса, работающего в фоновом режиме, используйте:

kill -STOP %job_id

Остановки сигнала SIGSTOP (паузы) процесс по существу тем же способом Ctrl+Z делают.

пример: kill -STOP %3.

источники: Как отправить сигналы в процессы в Linux и Unix и Как управлять фоновыми заданиями и заданиями переднего плана.

224
27.01.2020, 19:27
  • 1
    SIGCONT для меня; я использую kill -STOP и kill -CONT в предпочтении к запоминанию чисел так или иначе, но можно проверить kill -l напомнить себе о числовых значениях –  Useless 08.08.2012, 16:04
  • 2
    Выводы процесса к stderr, поэтому как я дам команду job и fg <jobid> в то время как процесс производит к терминалу? –  StackExchange for All 08.08.2012, 16:19
  • 3
    @Tim Просто вводит команду, как Вы обычно были бы. Пока задание является фоном, оно не читает то, что Вы вводите - Ваша оболочка. То, что Вы вводите, могло бы выглядеть поврежденным до Вас, но оболочка поймет это очень хорошо. –  AlexWebr 08.08.2012, 17:30
  • 4
    @AlexWebr: Спасибо, это работает! (1) Разве фоновое задание не принимает ввода и вывода включая "Ctrl+Z" и т.д., правильно? (2) Выполнение задания может в фоновом режиме быть приостановлено непосредственно? Если да, как? Если не, это должно быть сначала изменено для выполнения на переднем плане, прежде чем это сможет быть приостановлено? –  StackExchange for All 08.08.2012, 18:02
  • 5
    Может задание, работающее в фоновом режиме быть приостановленным непосредственно да: kill -STOP %job_id, как объясненный –  Useless 08.08.2012, 19:38

Ввести fg принести его к переднему плану.

11
27.01.2020, 19:27
  • 1
    Спасибо! Выводы процесса к stderr, поэтому как я дам команду fg <jobid> в то время как процесс производит к терминалу? –  StackExchange for All 08.08.2012, 16:16

Завершение процесса может быть сделано несколькими различными способами. Часто, с помощью консольной команды, отправка нажатия клавиши Ctrlc (символ прерывания по умолчанию) выходит из команды. Это работает, когда процесс выполняется в режиме переднего плана.

Если процесс работает в фоновом режиме, то сначала необходимо получить его Job ID с помощью команды ps, после чего можно использовать команду kill для завершения процесса следующим образом:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f
$kill 6738
Terminated

Здесь команда kill завершит процесс first_one. Если процесс игнорирует обычную команду kill, то можно использовать kill -9 с последующим идентификатором процесса следующим образом:

$kill -9 6738
Terminated
0
27.01.2020, 19:27

Это должно быть верно для любой оболочки с контролем задания, которую (по большей части) вы можете считать само собой разумеющейся, если только не имеете дело с поистине древней оболочкой. Это в стандарте POSIX , так что даже тире dash поддерживает управление заданием (при интерактивном запуске или с помощью -m).

Interactive

  • Ctrl+z приостановит текущую программу
  • bg будет фоном для последней приостановленной программы
    (используйте bg %2 с номером задания, который можно проверить с помощью jobs)
  • fg будет предшествовать последняя приостановленная программа

В zsh можно записать привязку ключей для неявного выполнения fg из запроса через другой Ctrl+z:

_zsh_cli_fg() { fg; }
zle -N _zsh_cli_fg
bindkey '^Z' _zsh_cli_fg

Вероятно, есть также умный способ имплицитно запустить bg после приостановления, но это кажется неразумным; по крайней мере для меня, большинство моих Ctrl+z использования, потому что Ctrl+c не получается; я хочу следовать за этим с e. g. kill %1 вместо bg, и я точно не хочу по умолчанию убивать! (Эта логика также распространяется на то, почему я больше не использую эту привязку ключей: Если я забиваю Ctrl+z для остановки процесса, то последнее, что я хочу, чтобы он возобновился!)

Неинтерактивный

Если вы находитесь в другом экземпляре оболочки (или другом пользователе, иногда включающем команды sudo), то вы, скорее всего, не сможете использовать номера заданий.

Вы все еще можете действовать в другом процессе, как только узнаете его идентификатор процесса (PID). Вы можете получить PID с помощью pgrep ..., или ps aux |grep ... (или из той же оболочки, jobs -l, или $! )) и вы можете запустить:

kill -STOP $PID  # suspend
kill -CONT $PID  # continue (resume)

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

killall -STOP program_name
pkill -STOP program_name
pkill -f -STOP program_name_or_args

Сигнал CONT на программу, остановленную с помощью Ctrl+z (а не bg'd), возобновит свой ход (на переднем плане), так же, как если бы вы fg.

Re: Стандартная ошибка

Правка в этом вопросе задает вопрос о стандартной ошибке:

Процесс выводит в stderr, так как же мне выдать команду fg во время вывода процесса на терминал?

Если только задание не имеет компонентов, которые являются фоновыми (или все задание является фоновым, возможно, с помощью kill -CONT), вы не должны видеть вывод, пока оно приостановлено.

Если он все еще выводит данные (будь то стандартный вывод или стандартная ошибка), это, конечно, сделает ваш терминал визуально загроможенным, но весь этот вывод будет проигнорирован, так как он не является частью вашего ввода. Это может затруднить понимание того, что вы не ввели никаких опечаток, но (слепого) набора fgEnter должно быть достаточно (если только у вас не несколько заданий, и это не самое последнее задание, в этом случае вам действительно понадобится дескриптор задания).

Если вам все же необходимо найти дескриптор задания, используйте другой терминал, чтобы послать ему сигнал STOP неинтерактивными методами, описанными выше. Это должно освободить дисплей (возможно, несколько раз нажмите Enter или запустите clear или Ctrl+L), чтобы затем можно было запустить jobs для поиска дескриптора задания, а затем запустить fg %N, где N - это этот номер.

35
27.01.2020, 19:27
  1. список заданий с помощью команды jobs
  2. Переместите целевую работу на передний план с помощью fg; например.:fg %4
  3. Нажмите CTRL Z, чтобы приостановить
  4. Чтобы запустить его в фоновом режиме, используйте bg; например.:bg %4
1
27.01.2020, 19:27

Теги

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