Фоновые и передние задания bash/zsh без добавления новых строк в сообщениях "продолжение/приостановка"

У меня есть процесс, который идет примерно так:

  • Запустите команду, которая генерирует кучу результатов в кучу файлов
  • Откройте файл в VIM
  • Изменить один из результатов
  • Фон vim, получить следующий результат, передний план vim
  • Повторяйте, пока список не будет завершен

Однако каждый раз, когда я создаю фоновый и передний план vim, bash/zsh печатает два сообщения, которые выглядят так:

[1]  + 4321 continued  nvim

[1]  + 4321 suspended  nvim

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

Есть ли способ получить сообщения "продолжение/приостановлено", чтобы избежать добавления новых строк? Как вариант, могу я их вообще подавить.

Ответы

Ответ 1

Методы для этого:


Это не самый эффективный способ сделать это, но это рабочий метод. Вот предполагаемая структура файла:

backgroundRun.sh
|
tmp
|
|_ outFile.txt

Вот как будет выглядеть backgroundRun.sh:

backgroundRun.sh:

#backgroundRun.sh
myCommand > tmp/outFile.txt 2>&1 &

Вывод кода:

./backgroundRun.sh
[email protected]~$

Как это устроено:

Основная концепция заключается в том, что весь вывод myCommand (смотрите backgroundRun.sh) хранится в tmp/outFile.txt при работе в фоновом режиме.

PS: outFile.txt будет пустым файлом (заполнителем).


Это эффективный метод. Проблема с этим в том, что вывод будет отражен на экране (если у вас есть). Просто такая простая команда:

(myCommand &) #Hit enter:
[email protected]~$

Как это работает: этот код о простоте; Все, что он делает, это команда (в фоновом режиме) в подоболочке.


Это еще один эффективный метод. Здесь вам нужен только один файл: backgroundRun.sh. Вот код:

backgroundRun.sh:

myCommand & > /dev/null 2>&1

Вывод кода:

./backgroundRun.sh
[email protected]~$

Как это устроено:

Он запускает команду, выводя ее в /dev/null. Если это не работает, выдает ошибку (2>&1).

PS: этот код будет работать только на * nix/POSIX системах, так как /dev/null отсутствует в других ОС

Ответ 2

Не совсем полное решение, но больше строк, чем позволит комментарий...

Следующее работает, чтобы уменьшить количество пустых строк (протестировано с bash на Raspbian/Debian, просто с vi). Ключевой шаг - запустить вложенный bash в интерактивном режиме, но скрыть вывод stderr:

bash -i 2>/dev/null

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

vi firstfile

Затем, когда вы выполняете фон vi (например, Ctrl Z), обычное сообщение [1]+ Stopped vi firstfile подавляется, как и предполагалось. Это общий результат на данный момент:

~ $ bash -i 2>/dev/null

Когда набирается fg (снова набирая вслепую), это возвращает вас к сеансу vi. Однако в следующий раз, когда вы vi фон vi, вы увидите следующую строку вывода, подтверждающую то, что было основано ранее:

~ $ bash -i 2>/dev/null
vi firstfile

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

fg>a

- a - просто фиктивный файл с коротким именем для сохранения, набрав fg>/dev/null.

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

Ответ 3

Если вы используете VIM, почему вы должны приостановить VIM? Все, что вам нужно, это последовательность:

% vim
:! youShellCommands
:e youFilename
.... over and over again

Это решает проблему более элегантно и без отключения диагностических сообщений.

ИЛИ ЖЕ

В bash введите следующую функцию:

function ff() { fg 2> /dev/null 1>&2 ; }

и используйте ff вместо fg. Отныне сессия будет выглядеть так:

% vi

[1] + Stopped vi
% ff
% ff
% ff

Не отключайте диагностические сообщения глобально для всего bash, потому что тогда работа в консоли будет чрезвычайно трудной. Как бы вы узнали, правильно ли выполнялись команды или нет.

РЕДАКТИРОВАТЬ: небольшая заметка. Ядро SIGTSTP отвечает за отправку процесса в фоновом режиме. Обычно запускают CTRL + Z (или иногда CTRL + Y). Он имеет номер 20. Вы можете вызвать его программно, например, с помощью kill -20 PIDNumber Чтобы избавиться от обратной связи, вам придется перезаписать службу сигналов SIGTSTP. Стоило того? Если да: в C напишите это так:

#include <stdio.h> 
#include <signal.h> 

void signalHandler(int sig_num) 
{ 
    // here is a new code for handling the signal
    // signal(SIGTSTP, ...etc.     
} 

signal(SIGTSTP, signalHandler);