Форум русскоязычного сообщества Ubuntu


Автор Тема: Непонятное поведение cut (bash/консоль)  (Прочитано 1282 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн kitaets

  • Автор темы
  • Активист
  • *
  • Сообщений: 569
  • Аналитик
    • Просмотр профиля
Постоянно использую cut, но в этот раз поведение утилиты меня весьма озадачило.
Нужно получить список носителей, и делаю я это так:
kitaets@laptop:~$ sudo parted -l | grep "/dev/" | cut -d' ' -f2
/dev/sda:
/dev/sdb:
/dev/sdc:

kitaets@laptop:~$
Видите пустую строку? Это жжж неспроста...

kitaets@laptop:~$ sudo parted -l | grep "/dev/"
Диск /dev/sda: 256GB
Диск /dev/sdb: 15,9GB
Диск /dev/sdc: 32,0GB
Ошибка: /dev/sdd: метка диска не определена
Последняя строка - именно она превращается в строку нулевой длины. Ошибка должна быть, ибо диск не содержит разделов.

Проверяю, подменив вызов parted на echo:
kitaets@laptop:~$ sudo echo "Ошибка: /dev/sdd: метка диска не определена" | grep "/dev/" | cut -d' ' -f2
/dev/sdd:
Вроде всё в порядке.
Кто-нибудь может объяснить, что я делаю не так?

P.S. Тут главный вопрос - не поиск алгоритма, а почему не работает то, что работать должно? Но можно и альтернативу предложить (задача - получить список дисков, и parted вроде бы оптимальный вариант).
«Если ты не наступил на грабли, это не значит, что их нет», – kitaets.

Оффлайн Self-Perfection

  • Активист
  • *
  • Сообщений: 331
  • Arch linux, KDE
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #1 : 24 Ноябрь 2013, 18:29:57 »
ПОЧЕМУ

Скорее всего, строка "Ошибка: /dev/sdd: метка диска не определена" выводится в stderr. Что можно проверить так (stdout в /dev/null, stderr всё равно будет выведен)
Код: (bash) [Выделить]
sudo parted -l >/dev/null
а привести поведение к ожидаемому, т.е. перенаправить stderr в stdout - так (первый вариант, специфичен для bash)
Код: (bash) [Выделить]
sudo parted -l |& grep "/dev/" | cut -d' ' -f2универсальный для любого shell
Код: (bash) [Выделить]
sudo parted -l 2>&1 | grep "/dev/" | cut -d' ' -f2
Правильное получение списка дисков
Посмотрите http://unix.stackexchange.com/a/4563/16246

Если у вас гарантированно есть свежий util-linux, то проще всего так
Код: (bash) [Выделить]
lsblk --noheadings --scsi -o NAME
Пользователь решил продолжить мысль 24 Ноябрь 2013, 18:36:35:
Или даже
Код: (bash) [Выделить]
lsblk --noheadings --scsi --paths -o KNAME
« Последнее редактирование: 24 Ноябрь 2013, 18:36:35 от Self-Perfection »
Читайте документацию, наставницу вашу!
Памятка по описанию проблем:
Для решения [такой-то задачи] делаю [такие-то действия], но вместо [ожидаемый результат] получаю [описание отличий].

Оффлайн kitaets

  • Автор темы
  • Активист
  • *
  • Сообщений: 569
  • Аналитик
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #2 : 24 Ноябрь 2013, 19:58:51 »
Спасибо!
Но предложенные вами варианты проверки отрабатывают так, будто строка идёт в stdout ???:
- по первой команде ничего не выдаётся;
- по другим двум командам (попытки перенаправления) выдаётся то же, что и без перенаправления, т.е. пустая строка в конце, как у меня;
- сообщение об ошибке явно идёт через grep, т.к. искомая подстрока подсвечивается:
Цитировать
kitaets@laptop:~$ sudo parted -l | grep "/dev/"
Диск /dev/sda: 256GB
Диск /dev/sdb: 15,9GB
Диск /dev/sdc: 32,0GB
Ошибка: /dev/sdd: метка диска не определена
Я выделил жирным то, что в терминале выделяется красным.
Вот такие странности :idiot2:
А вот здесь в первых двух строках не подсвечивается подстрока "/dev/", т.к. это действительно сообщения об ошибках:
Цитировать
kitaets@laptop:~$ sudo fdisk -l | grep " /dev/"
На диске /dev/sdc отсутствует верная таблица разделов
На диске /dev/sdd отсутствует верная таблица разделов
Диск /dev/sda: 256.1 Гб, 256060514304 байт
Диск /dev/sdc: 32.0 Гб, 32018268160 байт
Диск /dev/sdb: 15.9 Гб, 15937306624 байт
Диск /dev/sdd: 1027 МБ, 1027603456 байт
Наверное, заменю вызов parted на fdisk.
Но загадка пока осталась неразрешённой.
« Последнее редактирование: 24 Ноябрь 2013, 20:02:52 от kitaets »
«Если ты не наступил на грабли, это не значит, что их нет», – kitaets.

Оффлайн Self-Perfection

  • Активист
  • *
  • Сообщений: 331
  • Arch linux, KDE
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #3 : 24 Ноябрь 2013, 20:15:44 »
Да, невнимательно прочитал ваш первый пост, если grep строку ловит, значит она действительно пишется в stdout.

Ну значит дебажим по шагам. Добавим сохранение в файл того, что проходит через pipe
Код: (bash) [Выделить]
sudo parted -l | grep "/dev/" > debugfile
cut -d' ' -f2 debugfile

Если в таком варианте всё равно будет возникать лишняя пустая строка, то смотрим, что не так с содержимым этого файла. hexdump или xxd.

P.S.: Скорее всего для получения списка дисков права рута не нужны, sudo тут мозолит глаза.
Читайте документацию, наставницу вашу!
Памятка по описанию проблем:
Для решения [такой-то задачи] делаю [такие-то действия], но вместо [ожидаемый результат] получаю [описание отличий].

Оффлайн kitaets

  • Автор темы
  • Активист
  • *
  • Сообщений: 569
  • Аналитик
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #4 : 24 Ноябрь 2013, 20:40:57 »
Да, невнимательно прочитал ваш первый пост, если grep строку ловит, значит она действительно пишется в stdout.
А я об этом и не говорил, т.к. сам не обратил внимания :)

Ну значит дебажим по шагам. Добавим сохранение в файл того, что проходит через pipe
Код: (bash) [Выделить]
sudo parted -l | grep "/dev/" > debugfile
cut -d' ' -f2 debugfile
То же самое получается.

Если в таком варианте всё равно будет возникать лишняя пустая строка, то смотрим, что не так с содержимым этого файла. hexdump или xxd.
А вот тут что-то интересное:
kitaets@laptop:~$ cat /tmp/debugfile
Диск /dev/sda: 256GB
Диск /dev/sdb: 15,9GB
Диск /dev/sdc: 32,0GB
Ошибка: /dev/sdd: метка диска не определена                               
kitaets@laptop:~$ xxd /tmp/debugfile
0000000: d094 d0b8 d181 d0ba 202f 6465 762f 7364  ........ /dev/sd
0000010: 613a 2032 3536 4742 0ad0 94d0 b8d1 81d0  a: 256GB........
0000020: ba20 2f64 6576 2f73 6462 3a20 3135 2c39  . /dev/sdb: 15,9
0000030: 4742 0ad0 94d0 b8d1 81d0 ba20 2f64 6576  GB......... /dev
0000040: 2f73 6463 3a20 3332 2c30 4742 0a0d 2020  /sdc: 32,0GB.. 
0000050: 2020 2020 2020 2020 2020 2020 2020 2020                 
0000060: 2020 2020 2020 2020 2020 2020 2020 2020                 
0000070: 2020 2020 2020 2020 2020 2020 2020 2020                 
0000080: 2020 2020 2020 2020 2020 2020 2020 2020                 
0000090: 2020 2020 2020 2020 0dd0 9ed1 88d0 b8d0          ........
00000a0: b1d0 bad0 b03a 202f 6465 762f 7364 643a  .....: /dev/sdd:
00000b0: 20d0 bcd0 b5d1 82d0 bad0 b020 d0b4 d0b8   .......... ....
00000c0: d181 d0ba d0b0 20d0 bdd0 b520 d0be d0bf  ...... .... ....
00000d0: d180 d0b5 d0b4 d0b5 d0bb d0b5 d0bd d0b0  ................
00000e0: 0a                                       .
kitaets@laptop:~$


P.S.: Скорее всего для получения списка дисков права рута не нужны, sudo тут мозолит глаза.
Нужны, иначе молчит, как партизан.


Пользователь решил продолжить мысль 24 Ноябрь 2013, 20:51:15:
Вот ещё забавное:
kitaets@laptop:~$ sudo parted -l | grep "/dev/" | awk '{print $2}'
/dev/sda:
/dev/sdb:
/dev/sdc:
Ошибка:
kitaets@laptop:~$
« Последнее редактирование: 24 Ноябрь 2013, 20:51:15 от kitaets »
«Если ты не наступил на грабли, это не значит, что их нет», – kitaets.

Оффлайн Self-Perfection

  • Активист
  • *
  • Сообщений: 331
  • Arch linux, KDE
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #5 : 24 Ноябрь 2013, 21:24:28 »
Ну вот и разобрались. Перед словом "ошибка" куча пробелов, cut -d' ' -f2 выводит текст между первым и вторым пробелом, а между ними нет ничего.

awk странно себя ведёт, потому что перед пробелами есть символ \r (0x0D), который он и принимает за первое слово.

Итого в очередной раз доказан тезис, что грепать человекочитаемый вывод утилит в поисках нужной информации чревато ошибками. Это я намекаю, что правильно использовать lsblk. Ну или хотя бы
Код: (bash) [Выделить]
parted --list --machine
Читайте документацию, наставницу вашу!
Памятка по описанию проблем:
Для решения [такой-то задачи] делаю [такие-то действия], но вместо [ожидаемый результат] получаю [описание отличий].

Оффлайн kitaets

  • Автор темы
  • Активист
  • *
  • Сообщений: 569
  • Аналитик
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #6 : 24 Ноябрь 2013, 21:49:10 »
kitaets,
Код: (bash) [Выделить]
LANG=C sudo parted -l | grep "/dev/" | od -c?
0000000   D   i   s   k       /   d   e   v   /   s   d   a   :       2
0000020   5   6   G   B  \n   D   i   s   k       /   d   e   v   /   s
0000040   d   b   :       1   5   .   9   G   B  \n   D   i   s   k   
0000060   /   d   e   v   /   s   d   c   :       3   2   .   0   G   B
0000100  \n  \r                                                       
0000120                                                               
*
0000200                                                  \r   E   r   r
0000220   o   r   :       /   d   e   v   /   s   d   d   :       u   n
0000240   r   e   c   o   g   n   i   s   e   d       d   i   s   k   
0000260   l   a   b   e   l  \n
0000266

Итого в очередной раз доказан тезис, что грепать человекочитаемый вывод утилит в поисках нужной информации чревато ошибками. Это я намекаю, что правильно использовать lsblk. Ну или хотя бы
Код: (bash) [Выделить]
parted --list --machine
parted всё равно в результате выдаёт прелестное:
BYT;
/dev/sda:256GB:scsi:512:512:msdos:ATA SanDisk SSD U100;
1:1049kB:12,0GB:12,0GB:ext2::загрузочный;
2:12,0GB:256GB:244GB:::;
5:12,0GB:256GB:244GB:ext2::;

BYT;
/dev/sdb:15,9GB:scsi:512:512:msdos:Multiple Card Reader;
1:1049kB:15,9GB:15,9GB:ext2::;

BYT;
/dev/sdc:32,0GB:scsi:512:512:loop:Leef Surge;
1:0,00B:32,0GB:32,0GB:ext2::;

Ошибка: /dev/sdd: метка диска не определена

А lsblk, наверное, лучший вариант, сейчас прикручу вот в таком виде:
lsblk -no KNAME,TYPE,SIZE,MODEL | grep "disk"
«Если ты не наступил на грабли, это не значит, что их нет», – kitaets.

Оффлайн peregrine

  • FSM
  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 7188
  • Gentoo x64 Ubuntu 16.04.1 x64
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #7 : 24 Ноябрь 2013, 21:58:34 »
kitaets, а это не устроит
df -h | grep "/dev/sd"Ну или если совсем всё надо, то просто
df -h

Оффлайн kitaets

  • Автор темы
  • Активист
  • *
  • Сообщений: 569
  • Аналитик
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #8 : 24 Ноябрь 2013, 22:42:04 »
peregrine,
df не показывает неразбитых дисков.

Пользователь решил продолжить мысль 24 Ноябрь 2013, 22:50:08:
Self-Perfection,
А ведь с lsblk даже грепать не всегда надо:
lsblk -dno KNAME,TYPE,SIZE,MODELВообще здорово. Спасибо за подсказку!
« Последнее редактирование: 24 Ноябрь 2013, 22:50:08 от kitaets »
«Если ты не наступил на грабли, это не значит, что их нет», – kitaets.

Оффлайн victor00000

  • Забанен
  • Старожил
  • *
  • Сообщений: 15570
  • Глухонемой (Deaf)
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #9 : 24 Ноябрь 2013, 23:34:42 »
echo -e "p all\nq\n" | sudo parted
Нельзя друзья, дулу - AnrDaemon видите?
~.o

Оффлайн kitaets

  • Автор темы
  • Активист
  • *
  • Сообщений: 569
  • Аналитик
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #10 : 25 Ноябрь 2013, 01:14:40 »
echo -e "p all\nq\n" | sudo parted
Зачем так сложно, если есть parted -l? А в результате всё равно для неразмеченного диска выдаёт ту же ошибку:
Ошибка: /dev/sdd: метка диска не определена
«Если ты не наступил на грабли, это не значит, что их нет», – kitaets.

Оффлайн victor00000

  • Забанен
  • Старожил
  • *
  • Сообщений: 15570
  • Глухонемой (Deaf)
    • Просмотр профиля
Re: Непонятное поведение cut (bash/консоль)
« Ответ #11 : 25 Ноябрь 2013, 15:58:36 »
Цитировать
Ошибка: /dev/sdd: метка диска не определена
плохая.
Нельзя друзья, дулу - AnrDaemon видите?
~.o

 

Страница сгенерирована за 0.072 секунд. Запросов: 25.