LC_ALL=C </dev/urandom \
tr '1101001010
1100001001
1101110100
1011011000
1011110100
1+0 records in
0+1 records out
55 bytes (55 B) copied, 0.00176591 s, 31.1 kB/s
-7' '[0*128][1*]' |
dd ibs=50 cbs=10 conv=unblock count=1
Isso converterá todos os bytes ascii de entrada (que serão todos os bytes porque LC_ALL=C
está especificado) em um dos 0 ou 1 em uma distribuição par. Os primeiros 128 bytes entre 7
e 0-7
são convertidos em zeros e dd
em uns - e assim você pode usar todos os bytes de entrada e ainda gerar seqüências aleatoriamente ordenadas de apenas 1 ou 0.
Você estava certo em usar bs=
, mas não precisa definir seu tamanho de bloco \n
para obter 5 linhas de saída de 11 bytes (10 + count=1
ewline) uma peça. Em vez disso, você deve especificar um read()
single ibs=50
para um bloco de entrada de cbs=10
bytes, que pode ser dividido em blocos de conversão de 5 conv=unblock
sized e \n
ed em cbs-size anexando dd
ewline para cada bloco de conversão depois de remover todos os espaços à direita (dos quais você não tem nenhum) .
Então eu apenas corri e imprimi:
time (
LC_ALL=C </dev/urandom \
tr -dc 01 |
dd ibs=4k cbs=10 conv=unblock count=k|
grep \[^01])
Eu também aumentei um pouco a aposta para mostrar uma comparação de velocidade entre um método e outro e para demonstrar que a leitura de grep
de um pipe não é um problema se você ler em um fator de bloqueio que considera para o tamanho do buffer do utilitário de gravação. Então eu fiz primeiro:
1024+0 records in
9011+1 records out
4613735 bytes (4.6 MB) copied, 25.8898 s, 178 kB/s
( LC_ALL=C tr -dc 01 < /dev/urandom |\
dd ibs=4k cbs=10 conv=unblock count=k |...)\
0.80s user 25.42s system 101% cpu 25.921 total
... que não produziu saída no stdout (então dd
não correspondia a nada além de 0 ou 1) e o seguinte em stderr:
time (
LC_ALL=C </dev/urandom \
tr '1024+0 records in
9011+1 records out
4613735 bytes (4.6 MB) copied, 0.554202 s, 8.3 MB/s
( LC_ALL=C tr 'LC_ALL=C </dev/urandom \
tr '1101001010
1100001001
1101110100
1011011000
1011110100
1+0 records in
0+1 records out
55 bytes (55 B) copied, 0.00176591 s, 31.1 kB/s
-7' '[0*128][1*]' |
dd ibs=50 cbs=10 conv=unblock count=1
-7' '[0*128][1*]' \
< /dev/urandom|dd ibs=4k cbs=10 ...)\
0.61s user 0.36s system 171% cpu 0.571 total
-7' '[0*128][1*]' |
dd ibs=4k cbs=10 conv=unblock count=k|
grep '[^01]')
As informações acima informam que o pipeline gastou 25,5 segundos aguardando as chamadas do sistema. Está bem. Mas também nos diz que read()
lê todos os 1024 de seus registros de entrada de 4096 bytes completamente e nenhum deles foi truncado devido a um retorno inicial de tr
- e isso é porque dd
buffers transmitiram a saída em blocos de 4k.
De qualquer forma, fazer da outra maneira - ou converter todas as entradas aleatórias em um espectro de dispersão, foi o seguinte:
time (
LC_ALL=C </dev/urandom \
tr -dc 01 |
dd ibs=4k cbs=10 conv=unblock count=k|
grep \[^01])
Mais uma vez, não havia nada no stdout - então todos da saída de dd
era um de um zero ou um ou uma nova linha - e isso em stderr:
1024+0 records in
9011+1 records out
4613735 bytes (4.6 MB) copied, 25.8898 s, 178 kB/s
( LC_ALL=C tr -dc 01 < /dev/urandom |\
dd ibs=4k cbs=10 conv=unblock count=k |...)\
0.80s user 25.42s system 101% cpu 25.921 total
... que demonstra mais uma vez que tr
lê todos os 1024 registros de entrada completos + 0 registros de entrada truncados, mas o tempo de processamento é significativamente diferente. dd
e %code% são realmente capazes de trabalhar em paralelo aqui e, juntos, usam mais tempo total de usuário em núcleos separados do que o processo inteiro para concluir em apenas 6 segundos. Isso é um pouco mais rápido.