O Zsh fornece as MONITOR
e NOTIFY
opções, e você pode desativá-las para silenciar o relatório de status de trabalhos em segundo plano.
() {
setopt LOCAL_OPTIONS NO_NOTIFY NO_MONITOR
archey &
# ...
wait
}
Eu corro archey no meu .zshrc. O problema é que, devido à exibição do IP atual, às vezes pode ser executado como dois segundos. Para tornar isso menos perceptível, eu coloco em segundo plano assim:
# .zshrc
archey &
# lots of foo
wait
Desta forma, pode buscar o IP enquanto muitas outras coisas são feitas no meu zshrc. Mas agora o zsh exibe o ID do trabalho e do processo, e aquele archey termina todas as vezes:
Last login: Mon Jul 10 11:12:07 on ttys002
[1] 40436
# archey output
[1] + done archey
~
❯
Como o doc afirma que isso está sendo enviado para o stderr, tentei usar 2 > / dev / null, sem sucesso.
Como posso remover essas duas linhas?
Essas duas linhas são enviadas para stderr
do shell, não do processo. Você não pode fazê-los desaparecer do zsh.
Compreendendo pelos comentários, que você deseja ver a saída exibida, é necessário seguir três etapas:
wait
, pois isso depende do começo barulhento do plano de fundo 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 redirecionará a saída para um arquivo temporário e, quando feito, removerá um flagfile. Isso é necessário para a comunicação de volta.
start-archey.sh iniciará o wrap-archey.sh em segundo plano, eliminando o ruído no script principal e retornando imediatamente.
.zshrc irá configurar flagfile e resultfile, executar start-archey.sh silenciosamente em segundo plano, então fazer foo, então esperar que archey termine pesquisando o flagfile. Então limpa.
Se você não quiser usar um subshell, poderá usar:
# 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
}
Então:
silent_background archey # Or whatever command you want to background
Isso deve funcionar sem arquivos de script adicionais:
tmpf='mktemp'
{ archey ; echo 1 > "$tmpf" ; } &|
# foo
while [ ! -s "$tmpf" ] ; do sleep 0.1 ; done
rm "$tmpf"
unset tmpf
A chave é &|
operator. Ele executa o comando fornecido em segundo plano, mas o comando não é um trabalho, portanto, sua exibição não é spam. Você não pode usar wait
embora. Eu usei um arquivo temporário para detectar se archey
terminou.
Se o seu # foo
também produzir saída, você poderá ter uma condição de corrida. Nesse caso, é razoável capturar archey
output em outro arquivo temporário (como nesta outra resposta ) e imprimi-lo em o fim.
Eu não recomendo usar um único arquivo temporário para archey
de saída e como um acionador. Se você fizer isso, então while
test pode retornar true quando archey
ainda gravar no arquivo, eu acho.
Tags zsh