passando dd skip | procurar deslocamento como hexadecimal

11
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=3 2> /dev/null
d
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=0x3 2> /dev/null
f

Por que o segundo comando gera um valor diferente?

É possível passar o deslocamento para | procurar ddcomo um valor hexadecimal?

eadmaster
fonte

Respostas:

18

Por que o segundo comando gera um valor diferente?

Por razões históricas, ddconsidera xser um operador de multiplicação. Portanto, 0x3é avaliado como 0.

É possível passar o deslocamento skip | seek para dd como um valor hexadecimal?

Não diretamente, tanto quanto eu sei. Além da multiplicação usando o operador x, você pode sufocar qualquer número com o bsignificado de "multiplicar por 512" (0x200) e com o Ksignificado de "multiplicar por 1024" (0x400). Com GNU dd pode também utilizar sufixos de M, G, T, P, E, Ze Ypara significar multiplicar por 2 à potência de 20, 30, 40, 50, 60, 70, 80 ou 90, respectivamente, e pode usar superior ou inferior caso excepto para o bsufixo. (Existem muitos outros sufixos possíveis. Por exemplo, EBsignifica "multiplicar por 10 18 " e PiBsignifica "multiplicar por 2 50 ". Consulte info coreutils "block size"para obter mais informações, se você tiver uma instalação GNU.)

Você pode achar o arcano acima, anacrônico e nerd ao ponto do absurdo. Não se preocupe: você não está sozinho. Felizmente, você pode simplesmente ignorar tudo e usar a substituição aritmética do seu shell (o bash e outros shells compatíveis com Posix funcionarão, bem como alguns shells não Posix). O shell entende números hexadecimais e permite uma gama completa de operadores aritméticos escritos da maneira normal. Você só precisa cercar a expressão com $((...)):

# dd if=2013-Aug-uptime.csv bs=1 count=$((0x2B * 1024)) skip=$((0x37))
rici
fonte
Observe que a $((...))expansão aritmética do POSIX não é específica para o bash, você não precisa usá bash-lo, qualquer shell POSIX o fará. No entanto, note que em muitos reservatórios bash, inclusive , ele sofre divisão de palavras, portanto, deve ser citado.
Stéphane Chazelas
@StephaneChazelas: Isso é verdade, não é específico do bash. No entanto, ele não precisa de aspas. (Posix: "A expressão deve ser tratada como se estivesse entre aspas duplas, exceto que as aspas duplas dentro da expressão não são tratadas especialmente.") Se houvesse uma variável na expressão e seu valor incluísse um separador, então não seria um número válido; colocar aspas ao redor $((...))não mudará nada. O único caso em que consigo pensar em onde as aspas fariam alguma coisa é se você tivesse algo assim, IFS=4mas isso causaria todo tipo de caos.
rici 6/08/13
A seção que você cita é sobre o que está dentro $((...)). O POSIX é claro que a expansão de $((...))está sujeita à divisão de palavras . Deixando qualquer uma das expansões de comando / aritmética / variável não citadas no contexto da lista é o operador split + glob. Definir IFS = 4 não causaria todos os tipos de problemas se você não usar o operador split + glob onde não é necessário / desejado e defina o IFS toda vez que precisar desse operador split + glob.
Stéphane Chazelas
@StephaneChazelas: sim, o resultado numérico está sujeito à divisão de palavras. Mas é um número inteiro. Se você definir IFSalgo que inclua dígitos, algo que eu não acredito que já tenha feito, será necessário citar. Presumivelmente, se alguém estivesse fazendo isso, estaria ciente da necessidade, já que dificilmente é algo que provavelmente fará casualmente. Ou, pelo menos, dificilmente é algo que provavelmente vou fazer, ponto final. Eu não pretendo falar por você.
rici 6/08/13
1
@ iGurets: qual shell você está usando? (Por favor inclua a versão).
rici 21/10/19
0

Eu sei que esse é um tópico antigo, mas o problema ainda é mais relevante do que nunca, especialmente quando idiotas como eu vão e inadvertidamente lembram e extraem um 'arquivo cp fileA fileB' do histórico do bash quando o fileB ainda não está registrado no git sem suporte e contendo várias horas de codificação após uma noite toda: - /

Graças aos conceitos deste segmento, eu consegui recuperar completamente o meu arquivo perdido, mas perdi o meu em um servidor privado virtual remoto com um disco de 32Gb e muito pouca memória RAM (executando o Ubuntu 18.04), e todas as minhas tentativas usando 'grep' como acima morreria rapidamente com 'memória insuficiente'

No meu caso, foi o hexdump -C /dev/sdX1 | grep 'shortString'que veio em meu socorro. Ao contrário do grep, ele exibe apenas uma representação ASCII muito hexadecimal do hex, por isso é vital procurar apenas uma sequência curta e única, e lembre-se de que mesmo isso pode ser resolvido. Depois que ele emitiu algum endereço hexadecimal em que houve uma correspondência, eu pude usar 'dd' de uma maneira semelhante à anterior, exceto que eu achei que parecia estar padronizando para um tamanho de bloco de 4096, então eu não tinha apenas que converta o endereço de bytes hexadecimais em decimal, mas divida-o por 4096 para escalá-lo em blocos de 4k para o parâmetro skip do dd - sem ajuda, se esse número for muito grande para dd, a mensagem de erro parece estar reclamando por skip=ser inválida, e não pelo número passado a ele .

Muitos elogios para as pessoas que adicionaram dicas sobre o uso do bash com $((0xabcd))a facilidade de conversão obtaion hex-> dec :-)

Apenas minha palavra final - No meu caso, havia várias cópias do mesmo arquivo, todas próximas. Mas, subtraindo o endereço mais baixo do endereço mais alto relatado pelo hexdump, consegui identificar uma região de ~ 5 MB contendo todas as cópias possíveis, o que significava que eu poderia direcionar o dd para o endereço mais baixo e extrair toda a região para um arquivo temporário. O editor Vim agora lida com conteúdo binário de maneira bastante simples, para que você possa examinar o arquivo temporário e remodelá-lo conforme necessário.

JonathanH-UK
fonte