1

Я запускаю archey в моем .zshrc. Проблема в том, что из-за отображения текущего IP-адреса он иногда может работать как две секунды. Чтобы сделать это менее заметным, я поместил его на задний план, например так:

# .zshrc
archey &
# lots of foo
wait

Таким образом, он может получить IP, в то время как в моем zshrc делается много других вещей. Но теперь zsh отображает идентификатор задания и процесса, и этот archey завершается каждый раз:

Last login: Mon Jul 10 11:12:07 on ttys002
[1] 40436

# archey output

[1]  + done       archey

~
❯

Поскольку в документе говорится, что это отправляется в stderr, я попытался использовать 2>/dev/null, но безуспешно.

Как я могу удалить эти две строки?

4 ответа4

2

Zsh предоставляет опции MONITOR и NOTIFY , и вы можете отключить их, чтобы отключить отчет о состоянии фоновых заданий.

() {
  setopt LOCAL_OPTIONS NO_NOTIFY NO_MONITOR
  archey &
  # ...
  wait
}
1

Если вы не хотите использовать подоболочку, вы можете использовать:

# Run the command given by "$@" in the background
silent_background() {
  if [[ -n $ZSH_VERSION ]]; then  # zsh:  https://superuser.com/a/1285272/365890
    setopt local_options no_notify no_monitor
    # We'd use &| to background and disown, but incompatible with bash, so:
    "$@" &
  elif [[ -n $BASH_VERSION ]]; then  # bash: https://stackoverflow.com/a/27340076/5353461
    { 2>&3 "$@"& } 3>&2 2>/dev/null
  else  # Unknownness - just background it
    "$@" &
  fi
  disown &>/dev/null  # Close STD{OUT,ERR} to prevent whine if job has already completed
}

Затем:

silent_background archey #  Or whatever command you want to background
1

Эти две строки выводятся в stderr оболочки, а не процесса. Вы не можете заставить их исчезнуть из Zsh.

Исходя из комментариев, вы хотите увидеть вывод, вам нужно сделать три шага:

  1. Чтобы избежать шума запуска арчи в фоновом режиме, вы должны запустить его из скрипта
  2. Чтобы сообщить результаты archey обратно в основной скрипт, вы должны использовать временный файл или что-то подобное
  3. Чтобы понять, когда он закончится, вы не можете использовать wait как это зависит от шумного фонового запуска

wrap-archey.sh:

#/bin/sh
archey >"$1" 2>&1
rm "$2"

start-archey.sh:

/path/to/wrap-archey.sh "$1" "$2" >/dev/null 2>&1 &

.zshrc:

ARCHEYOUT=$(mktemp)
ARCHEYFLAG=$(mktemp)
/path/to/start-archey.sh "$ARCHEYOUT" "$ARCHEYFLAG" >/dev/null 2>&1
#
# lots of foo
#
while test -f "$ARCHEYFLAG"; do sleep 0.1 ; done
cat "$ARCHEYOUT"
rm "$ARCHEYOUT"

wrap-archey.sh перенаправит вывод в временный файл, а когда закончит, удалит флаговый файл. Это нужно для обратной связи.

start-archey.sh запустит wrap-archey.sh в фоновом режиме, удалив шумы в основном скрипте и вернувшись немедленно.

.zshrc установит flagfile и resultfile, автоматически запустит start-archey.sh в фоновом режиме, затем выполнит foo, затем дождется завершения archey, опросив flagfile. Тогда это очищается.

0

Это должно работать без дополнительных файлов скриптов:

tmpf=`mktemp`
{ archey ; echo 1 > "$tmpf" ; } &|

# foo

while [ ! -s "$tmpf" ] ; do sleep 0.1 ; done
rm "$tmpf"
unset tmpf

Ключ &| оператор. Он запускает данную команду в фоновом режиме, но команда не является заданием, поэтому ваш дисплей не является спамом. Вы не можете использовать wait хотя. Я использовал временный файл, чтобы определить, закончил ли archey .

Если ваш # foo также выдает результат, вы можете испытать состояние гонки. В этом случае целесообразно записать вывод archey в другой временный файл (как в этом другом ответе) и распечатать его в конце.

Я не рекомендую использовать один временный файл для вывода archey и в качестве триггера. Я думаю, если вы сделаете это, то в while test может вернуть true, когда archey все еще пишет в файл.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .