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 / 787672
Accepted
matt_bianco
matt_bianco
Asked: 2024-12-05 18:33:31 +0800 CST2024-12-05 18:33:31 +0800 CST 2024-12-05 18:33:31 +0800 CST

Execução condicional de comandos com base na saída grep no script de shell

  • 772

Estou usando um script para transcodificar um monte de filmes usando a versão de linha de comando do HandBrake. Estou usando uma versão modificada do script aqui:

https://gist.github.com/ralphcrisostomo/56fc395b1646bd55aeeb2eb442043887

O problema que tenho é que a transcodificação trava de forma não reproduzível em um pequeno subconjunto de filmes. Isso é acompanhado por um erro muito específico no stderr.

O que eu gostaria de fazer é 1) seguir o stdout (mas não o stderr) na tela, 2) monitorar o stderr para a condição de erro e 3) se a condição de erro for satisfeita, encerrar o processo do HandBrake, registrar o arquivo problemático e passar para o próximo.

Atualmente, o comando de transcodificação se parece com isto:

echo "" | HandBrakeCLI -i "$ITEM" -o "$OUTPUT" --preset="$PRESET" $OPTS 2> /dev/null

que satisfaz 1).

Seguindo os conselhos aqui:

Como executar grep no fluxo de erro padrão (stderr)?

Posso executar grep com sucesso no fluxo de erros para a palavra relevante, por exemplo

echo "" | HandBrakeCLI -i "$ITEM" -o "$OUTPUT" --preset="$PRESET" 2> >(grep -i error)

ou

echo "" | HandBrakeCLI -i "$ITEM" -o "$OUTPUT" --preset="$PRESET" 3>&2 2>&1 1>&3- | grep -i "error"

No entanto, tudo isso fará com que ele imprima a linha relevante do stderr na tela. Não está claro para mim como posso usar isso para executar comandos específicos, por exemplo, kill HandBrakeCLI ; echo $ITEM >> err.log

Tentei usar grep -q para testar se a correspondência foi bem-sucedida assim:

echo "" | HandBrakeCLI -i "$ITEM" -o "$OUTPUT" --preset="$PRESET" $OPTS 3>&2 2>&1 1>&3- | grep -q "error" && echo "error found" ; echo $ITEM >> failed.txt

Mas o script simplesmente sai ao encontrar o erro, sem passar para o próximo item do loop.

Qualquer ajuda será bem-vinda!

atualizado para responder à pergunta de Terdon:

Também fiquei curioso sobre o echo inicial "" | na invocação do HandBrake. Estava no script original referenciado no topo da consulta, mas também não está claro para mim por que é necessário. Estou executando isso no MacOS. O script completo é

#!/bin/bash

SOURCE=$1
ENCODER=$2
OPTS=$3

TOTAL=$(find "$SOURCE" \! -name ".*" -type f | wc -l)
CURR=0
DESTINATION="PROCESSED"

ENCODER=${ENCODER:="hw"}

# Create directorys
[[ -d $DESTINATION ]] || mkdir -p $DESTINATION

while IFS= read -d '' -r ITEM
do
  RES=`ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of default=nw=1 "$ITEM" | grep 'height*' | cut -c 8-`
  FILE=${ITEM##*/}
  EXT=${ITEM##*.}
  EXT=$(echo $EXT | tr "[:upper:]" "[:lower:]")
  OUTPUT="$DESTINATION/${FILE%.*}.$EXT"

  # Get the right preset
  if [[ "$RES" == "2160" ]] && [[ "$ENCODER" == "hw" ]]
  then
    PRESET="H.265 Apple VideoToolbox 2160p 4K"
  elif [[ "$RES" == "2160" ]] && [[ "$ENCODER" == "sw" ]]
    then
      PRESET="Fast 2160p60 4K HEVC"
  elif [[ "$RES" != "2160" ]] && [[ "$ENCODER" == "hw" ]]
    then
      PRESET="H.265 Apple VideoToolbox 1080p"
  elif [[ "$RES" != "2160" ]] && [[ "$ENCODER" == "sw" ]]
    then
      PRESET="Fast 1080p30"
    fi
  
  echo "Processing" $FILE "using preset" $PRESET
  echo "" | HandBrakeCLI -i "$ITEM" -o "$OUTPUT" --preset="$PRESET" $OPTS 2> /dev/null

  CURR=$((CURR + 1))
  echo "done" $CURR "of"$TOTAL
    
done< <(find "$SOURCE" \( -iname '*.mp4' -or -iname '*.mov'  -or -iname '*.MP4' -or -iname '*.MOV' \) -print0)

Atualização 061224

Seguindo a sugestão de markp-fuso, modifiquei a linha que chama o HandBrake da seguinte forma:

echo "" | HandBrakeCLI -i "$ITEM" -o "$OUTPUT" --preset="$PRESET" 2> >(grep -i error && { pkill HandBrakeCLI ; echo $ITEM >> err.log; })

Isso imprime o erro relevante no stdout quando encontrado, mas só executa a segunda parte (por exemplo, matando o processo e registrando o resultado) quando a codificação atual é concluída. Se a codificação simplesmente travar e continuar gerando o mesmo erro, a segunda parte do comando não será executada. Se eu alterar a linha para:

echo "" | HandBrakeCLI -i "$ITEM" -o "$OUTPUT" --preset="$PRESET" 2> >(grep -q error && { pkill HandBrakeCLI ; echo $ITEM >> err.log; })

Então o comando grep sai ao encontrar o erro, o script inteiro sai sem processar mais nenhum item no loop. Estranhamente, porém, se eu matar o processo HandBrake de outro shell quando o encode trava, ele então moverá corretamente para o próximo item.

bash
  • 1 1 respostas
  • 65 Views

1 respostas

  • Voted
  1. Best Answer
    matt_bianco
    2024-12-06T21:10:00+08:002024-12-06T21:10:00+08:00

    Com base na resposta de markp-fuso, alterei a linha de invocação do HandBrake para:

    echo "" | HandBrakeCLI -i "$ITEM" -o "$OUTPUT" --preset="$PRESET" 2> >(grep -q error && { pkill HandBrakeCLI ; echo $ITEM >> err.log; })
    

    Havia linhas adicionais no script que exigiam a conclusão bem-sucedida da codificação, então eu tornei isso condicional à codificação bem-sucedida (ou seja, condição de erro não atendida). Uma vez removido, o script funcionou como esperado.

    • 0

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

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

    • 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

    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
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • 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
    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

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