AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 414892
Accepted
PhilBot
PhilBot
Asked: 2018-01-05 16:31:27 +0800 CST2018-01-05 16:31:27 +0800 CST 2018-01-05 16:31:27 +0800 CST

Como encerrar o comando tee do Linux sem matar o aplicativo do qual ele está recebendo

  • 772

Eu tenho um script bash que é executado enquanto a máquina Linux estiver ligada. Eu começo como mostrado abaixo:

( /mnt/apps/start.sh 2>&1 | tee /tmp/nginx/debug_log.log ) &

Após o lançamento, posso ver o comando tee na saída do meu ps , conforme mostrado abaixo:

$ ps | grep tee
  418 root       0:02 tee /tmp/nginx/debug_log.log
3557 root       0:00 grep tee

Eu tenho uma função que monitora o tamanho do log que o tee produz e mata o comando tee quando o log atinge um determinado tamanho:

monitor_debug_log_size() {
                ## Monitor the file size of the debug log to make sure it does not get too big
                while true; do
                                cecho r "CHECKING DEBUG LOG SIZE... "
                                debugLogSizeBytes=$(stat -c%s "/tmp/nginx/debug_log.log")
                                cecho r "DEBUG LOG SIZE: $debugLogSizeBytes"
                                if [ $((debugLogSizeBytes)) -gt 100000 ]; then
                                                cecho r "DEBUG LOG HAS GROWN TO LARGE... "
                                                sleep 3
                                                #rm -rf /tmp/nginx/debug_log.log 1>/dev/null 2>/dev/null
                                                kill -9 `pgrep -f tee`
                                fi
                                sleep 30
                done
}

Para minha surpresa, matar o comando tee também mata por instância start.sh. Por que é isso? Como posso encerrar o comando tee , mas fazer com que meu start.sh continue em execução? Obrigado.

linux scripting
  • 2 2 respostas
  • 6192 Views

2 respostas

  • Voted
  1. Best Answer
    Wildcard
    2018-01-05T17:04:25+08:002018-01-05T17:04:25+08:00

    Quando teeterminar, o comando que o alimenta continuará em execução, até tentar gravar mais saída. Em seguida, obterá um SIGPIPE (13 na maioria dos sistemas) por tentar gravar em um pipe sem leitores.

    Se você modificar seu script para interceptar o SIGPIPE e tomar alguma ação apropriada (como parar de gravar a saída), você poderá fazer com que ele continue depois que o tee for encerrado.


    Melhor ainda, em vez de matar tee , use logrotatecom a copytruncateopção de simplicidade.

    Para citar logrotate(8):

    copytruncate

    Trunque o arquivo de log original no local depois de criar uma cópia, em vez de mover o arquivo de log antigo e, opcionalmente, criar um novo. Ele pode ser usado quando algum programa não pode ser instruído a fechar seu arquivo de log e, portanto, pode continuar gravando (anexando) no arquivo de log anterior para sempre. Observe que há uma fatia de tempo muito pequena entre copiar o arquivo e truncá-lo, portanto, alguns dados de registro podem ser perdidos. Quando esta opção é usada, a opção de criação não terá efeito, pois o arquivo de log antigo permanece no lugar.

    • 36
  2. Charles Duffy
    2018-01-06T14:07:35+08:002018-01-06T14:07:35+08:00

    Explicando o "porquê"

    Resumindo: se as falhas de gravação não causassem a saída de um programa (por padrão), teríamos uma bagunça. Considere find . | head -n 10- você não quer findcontinuar rodando, escaneando o resto do seu disco rígido, depois headde pegar as 10 linhas necessárias e prosseguir.

    Fazendo melhor: gire dentro do seu registrador

    Considere o seguinte, que não usa teenada, como um exemplo demonstrativo:

    #!/usr/bin/env bash
    
    file=${1:-debug.log}                     # filename as 1st argument
    max_size=${2:-100000}                    # max size as 2nd argument
    size=$(stat --format=%s -- "$file") || exit  # Use GNU stat to retrieve size
    exec >>"$file"                           # Open file for append
    
    while IFS= read -r line; do              # read a line from stdin
      size=$(( size + ${#line} + 1 ))        # add line's length + 1 to our counter
      if (( size > max_size )); then         # and if it exceeds our maximum...
        mv -- "$file" "$file.old"            # ...rename the file away...
        exec >"$file"                        # ...and reopen a new file as stdout
        size=0                               # ...resetting our size counter
      fi
      printf '%s\n' "$line"                  # regardless, append to our current stdout
    done
    

    Se executado como:

    /mnt/apps/start.sh 2>&1 | above-script /tmp/nginx/debug_log
    

    ...isso começará anexando a /tmp/nginx/debug_log, renomeando o arquivo para /tmp/nginx/debug_log.oldquando houver mais de 100 KB de conteúdo. Como o próprio registrador está fazendo a rotação, não há tubo quebrado, nenhum erro e nenhuma janela de perda de dados quando a rotação ocorre - cada linha será gravada em um arquivo ou outro.

    Obviamente, implementar isso no bash nativo é ineficiente, mas o exemplo acima é ilustrativo. Existem vários programas disponíveis que implementarão a lógica acima para você. Considerar:

    • svlogd, o registrador de serviços do pacote Runit.
    • s6-log, uma alternativa mantida ativamente da suíte skanet.
    • multilogda DJB Daemontools, o avô desta família de ferramentas de supervisão e monitoramento de processos.
    • 3

relate perguntas

  • Inicie/pare o serviço systemd usando o atalho de teclado [fechado]

  • Necessidade de algumas chamadas de sistema

  • Renomeie (acrescentar) arquivos CSV em massa com base em um valor dentro

  • astyle não altera a formatação do arquivo de origem

  • Passe o sistema de arquivos raiz por rótulo para o kernel do Linux

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve