Problemas com comandos de encadeamento

0

Sooo Eu estou tentando registrar meu hashrate ethminer, no entanto estou tendo alguns problemas para encadear a saída de um egrep / grep em outro, eu até tentei com comandos diferentes (sed / cat ...) nenhum parece realmente ter qualquer tipo de saída, eu não posso nem redirecionar stdout para um arquivo! A parte estranha; quando eu não tento encadear ou redirecionar nada, ele imprime o que é suposto no terminal!

após cerca de 2h de pesquisa, eu ainda estou com o mesmo erro (provavelmente o meu, mas não consigo entender) e mesmo depois de copiar algumas coisas que encontrei, ainda estou no mesmo lugar. .

aqui está o comando que gostaria de filtrar:

/home/USER/ethminer -U -S eu1.ethermine.org:4444 -O 0x*****************.********** --cuda-parallel-hash 4

imprima isso (ele gera cerca de um pouco mais de uma linha / segundo, e isso precisa ser executado basicamente para sempre):

  ℹ  23:36:26|CUDA0     set work; seed: #4be89018, target:  #0000000112e0
  ℹ  23:36:26|CUDA0     set work; seed: #4be89018, target:  #0000000112e0
  m  23:36:28|ethminer  Speed  20.01 Mh/s    gpu/0 20.01  [A0+0:R0+0:F0] Time: 00:00
  m  23:36:30|ethminer  Speed  22.13 Mh/s    gpu/0 22.13  [A0+0:R0+0:F0] Time: 00:00

A coisa que me interessa é a parte depois de Speed, apesar de haver personagens escondidos, aqui está o que um acorrentado

  cat -e 

exibe:

^[[32m  m  ^[[35m23:38:10^[[0m^[[30m|^[[34methminer^[[0m  Speed ^[[1;36m 23.09^[[0m Mh/s    gpu/0 ^[[36m23.09^[[0m  [A0+0:R0+0:F0] Time: 00:00^[[0m$

observe a "Velocidade ^ [[1; 36m 23.09", estou usando o 'm' como referência para encontrar o hashrate na expressão com m [[:digit:]]+\.[[:digit:]]{2} (btw você verá que eu preciso redirecionar o stderr para o stdout, isso é porque ethminer parece saída do hashrate no canal stderr ... meio estranho ...) Isso me dá:

/home/USER/ethminer -U -S eu1.ethermine.org:4444 -O 0x*****************.********** --cuda-parallel-hash 4 2>&1 | cat -e | egrep -o --color=never "m [[:digit:]]+\.[[:digit:]]{2}" | egrep -o [[:digit:]]+\.[[:digit:]]{2}$

isso me mostra o que é suposto fazer:

m 0.00
m 15.74
m 19.41

Então, até agora, está tudo bem ... mas depois dessa ... tudo está ficando estranho ... Eu não consegui obter nenhuma saída ... nem mesmo no meu terminal a partir de qualquer comando encadeado, Eu tentei muitas coisas, de jogar com o redirecionamento de stderr e stdout sobre todos os lugares, tentei cat: sem saída, jogou um pouco com sed: sem sorte, com grep: não mais chance do que com sed ... Idealmente eu gostaria de algo assim:

/home/USER/ethminer -U -S eu1.ethermine.org:4444 -O 0x*****************.********** --cuda-parallel-hash 4 2>&1 | cat -e | egrep -o --color=never "m [[:digit:]]+\.[[:digit:]]{2}" | egrep -o [[:digit:]]+\.[[:digit:]]{2}$ >> /home/USER/mining.log

Qual seria a saída:

22.26
22.47

no arquivo mining.log ...

Ajuda!

EDITAR: O ethminer está vindo daqui: link esta é a versão 0.12.0

UDATE: A resposta do egmont acabou funcionando, se eu entendi corretamente, isso é por causa da maneira como os dados enviados através de pipes são armazenados em buffer com o ethminer ... aqui está o comando que acabei usando:

stdbuf -oL ethminer [arguments] 2>&1 | stdbuf -oL cat -e | stdbuf -oL egrep -o "m [0-9]+\.[0-9]{2}" | stdbuf -oL egrep -o "[0-9]+\.[0-9]{2}" >> mining.log
    
por Celivalg 27.11.2017 / 23:54

2 respostas

0

O comportamento padrão, quando a saída é gravada em um terminal, deve ser armazenado em buffer de linha, no entanto, quando direcionado para um arquivo ou para outro processo usando um pipe, ele é armazenado em buffer em talvez 4kB ou 8kB de dados. Ou seja, o seu etniner precisa imprimir tantos dados para o primeiro fragmento a fim de ser escrito e ficar disponível para a próxima fase em sua linha do tempo.

Use stdbuf para ativar o modo de buffer de linha mesmo se a saída for para outro processo, por exemplo, stdbuf -oL ethminer [parameters] | cat-or-grep-or-whatever .

Pelo mesmo motivo, se você tiver um pipeline mais longo, provavelmente todas as fases, mas a última, precisam ser alteradas para o buffer de linha, algo como: stdbuf -oL ethminer | stdbuf -oL cat -e | stdbuf -oL egrep pattern1 | egrep pattern2 .

As cores são irrelevantes para essa história, embora, como apontado em uma resposta diferente, o ethminer deva detectar se a saída padrão não está conectada a um terminal e não deve emitir códigos de cores nesse caso.

    
por egmont 28.11.2017 / 12:12
1

A maioria dos programas de linha de comando que fornecem saída de terminal colorido são inteligentes o suficiente para reconhecer quando sua saída não está indo para um terminal e suprimem os códigos de cores. Parece que ethminer não é.

Sua solução foi converter os códigos ANSI não imprimíveis em texto sem formatação usando cat -e e, em seguida, analisá-los. Uma solução alternativa (e possivelmente mais robusta) pode ser remover os códigos de cores - uma forma de fazer isso é usar o perl Módulo de duração :: ANSIColor , por exemplo

/home/USER/ethminer -U -S eu1.ethermine.org:4444 -O 0x*****************.********** --cuda-parallel-hash 4 2>&1 | 
  perl -MTerm::ANSIColor=colorstrip -lne 'print colorstrip $_' | grep ...

No entanto, se fizermos , poderemos usar perl no lugar de grep para fazer a correspondência. Há muitas maneiras de fazer isso - aqui está uma:

  • divida a linha em uma matriz separada por espaços em branco @F
  • chame colorstrip on @F e salve os resultados em @a
  • encontre o índice do elemento da matriz correspondente a Speed , procure e imprima o próximo elemento

ex.

/home/USER/ethminer -U -S eu1.ethermine.org:4444 -O 0x*****************.********** --cuda-parallel-hash 4 2>&1 | 
  perl -MTerm::ANSIColor=colorstrip -alne '@a = colorstrip @F; print map { $a[$_+1] } grep { $a[$_] eq "Speed" } 0..$#a'
    
por steeldriver 28.11.2017 / 02:34