На самом деле это единственный раздел про unix на этом форуме
Модераторы: /dev/random , Модераторы разделов
жучара
Сообщения: 1051
ОС: астралинукс
Сообщение
жучара » 30.03.2024 23:34
Друзья! Работаю в
bash . Казалось бы, вот код. Считаем в цикле файл
foo и выведем байты на экран в виде чисел:
Shell
$ cat foo | while read -n 1 -d '' c; do A=$c ; printf '0x%0*x ' 2 "'$A"; done ; echo
0x00 0x00 0x00
$
Так, а меж тем файл
foo на самом деле такой (трёхбайтовый):
0x0A 0x00 0x0A
Даже я не знаю, где я прокололся, то ли я считываю неправильно, то ли байт в число преобразую неправильно. Преобразование байта в число одно на весь интернет и то сами видите, какое:
https://superuser.com/questions/597620/how-to-convert-ascii-character-to-integer-in-bash
Там символ преобразуют, но другого-то всё равно ничего нет
Спасибо, кто откликнется.
Я просто читаю маны.
Bizdelnick
Модератор
Сообщения: 21036
Статус: nulla salus bello
ОС: Debian GNU/Linux
Сообщение
Bizdelnick » 31.03.2024 01:25
man bash-builtins писал(а): If delim is the empty string, read will terminate a line when it reads a NUL character.
Пишите правильно:
в консоли
вк у́пе (с чем-либо)
в о бщем
воо бще в течение (часа)
новичо к
ню анс
по у молчанию приемле мо
проблем а
пробо вать
траф ик
жучара
Сообщения: 1051
ОС: астралинукс
Сообщение
жучара » 31.03.2024 02:59
Bizdelnick , я только запутался ещё больше. Начать с того что если это так, то у меня имеется всего один нулевой символ. Значит, оно должно всё это считать ОДИН раз. А оно считывает три раза. Непонятно.
...Так вот надо было сразу:
Код: Выделить всё
#include <stdio.h>
int main(void)
{
int c;
while((c=getchar())!=EOF)
{
printf ("0x%0*x ", 2, c);
}
return 0;
}
а
bash , наверное, не умеет побайтно.
Я просто читаю маны.
ormorph
Сообщения: 2913
ОС: Gentoo
Сообщение
ormorph » 31.03.2024 06:42
жучара писал(а): ↑ 31.03.2024 02:59
а bash, наверное, не умеет побайтно.
Точнее команда read. Если используется -n 1, то символ 0a воспринимается как конец и вместо него прописывается 00, зачем это сделано не знаю.
На это как раз есть другие команды(программы), их вывод можно обрабатывать.
Shell
$ cat foo|od -t x1 -A n|sed -e 's/^./0x/' -e 's/ / 0x/g'
ormorph
Сообщения: 2913
ОС: Gentoo
Сообщение
ormorph » 31.03.2024 08:19
Как то так вроде работает.
Shell
#!/bin/bash
FILE="foo"
i=0
while read -n 1 -d ''
do
read -N 1 byte < <(dd if=${FILE} bs=1 count=1 skip=$i 2>/dev/null)
printf '0x%02x ' "'$byte"
i=$[i+1]
done <"${FILE}"
IMB
Сообщения: 2565
ОС: Debian
Сообщение
IMB » 31.03.2024 10:59
ormorph
Сообщения: 2913
ОС: Gentoo
Сообщение
ormorph » 31.03.2024 12:20
Для того чтобы убедитьcя что в bash можно работать побайтно, пример.
Shell
#!/bin/bash
FILE="hello"
OUT_FILE=hello2
len=$(ls -l ${FILE} |awk '{print $5}')
copy_bytes() {
for ((i=0; i<$len; i++))
do
read -N 1 byte < <(dd if=${FILE} bs=1 count=1 skip=$i 2>/dev/null)
echo -n -e $(printf '\\x%01x' "'$byte") | dd of=${OUT_FILE} bs=1 count=1 seek=$i 2>/dev/null
done
}
copy_bytes
chmod +x "${OUT_FILE}"
echo "len=$i"
Для примера собрал обычный Hello World на C, и его попробовал считать и записать по байту. Бинарник запустился, следовательно это работает. Но это работает очень медленно. Правда не пойму для чего это было нужно.
Bizdelnick
Модератор
Сообщения: 21036
Статус: nulla salus bello
ОС: Debian GNU/Linux
Сообщение
Bizdelnick » 01.04.2024 02:28
Когда мне понадобилось что-то подобное, я
использовал od . Но вообще это изврат. Лучше взять нормальный язык программирования.
Пишите правильно:
в консоли
вк у́пе (с чем-либо)
в о бщем
воо бще в течение (часа)
новичо к
ню анс
по у молчанию приемле мо
проблем а
пробо вать
траф ик
ormorph
Сообщения: 2913
ОС: Gentoo
Сообщение
ormorph » 01.04.2024 07:29
Bizdelnick писал: ↑ 01.04.2024 02:28
Но вообще это изврат. Лучше взять нормальный язык программирования.
Ещё какой. Если хочется совместить с bash, то хотя бы обработчик тогда должен быть на другом языке, так скорость вырастет в разы. Пайтон с этим справляется вполне норм.
Spoiler Код: Выделить всё
#!/usr/bin/env python
import os
import sys
if len(sys.argv) < 2:
print("Missing argument")
sys.exit()
file = sys.argv[1]
if not os.path.isfile(file):
print("No such File: " + file)
sys.exit()
fd = open(file, 'rb')
while True:
buf=fd.read(1)
print(buf.hex(), end=' ')
if buf == b"":
break
fd.close()