LINUX.ORG.RU

Как отлаживать busybox-скрипты?

 


0

3

Как отлаживать busybox-скрипты? В bash есть переменная PS4 и есть $LINENO и $BASH_SOURCE В busybox PS4 есть, но этих переменных нет. Или я не нашел аналоги. А я хочу подкрутить койчего в init, который представляет из себя busybox-скрипт. busybox умеет как и bash с ключом -x выводить то, что исполняет, но без номеров строк и имени файла читать этот выхлоп - ад.

А комменты он вывод? Если да, можешь вначале поставить комменты тип # 5 в конце каждой строки, а потом удалить их sed-ом или awk-ом

Xenius ★★★★★
()
Ответ на: комментарий от Xenius

Да! Проверил. Рабочий вариант - сначала скриптом добавить каменты, отладить, потом убрать...

chabapok
() автор топика
Ответ на: комментарий от Xenius

А вообще я рано обрадовался. Оно работает - но странно. Например цикл for он сначала выводит с каментами - а только потом исполняет, и исполняя печатает без каментов. И это если запускать с ключом -vx. Если просто -x, то каменты не выводит.

chabapok
() автор топика
Ответ на: комментарий от chabapok

Ну да, есть такое. Но всё равно же лучше чем совсем без номеров, не так ли?

А вообще может тебе сам бизибокс пропатчить?

Xenius ★★★★★
()
Ответ на: комментарий от chabapok

А где она есть? В bash тоже нет (как ключ для set). И, насколько я понимаю, posix не предусмотрена...

Кстати я прочитал описание BASH_LINENO и BASH_SOURCE и не совсем понял, как это использовать для дебага

Xenius ★★★★★
()
Последнее исправление: Xenius (всего исправлений: 1)
Ответ на: комментарий от chabapok

Просто мне несколько странно, что в нем нету такой штатной фичи.

Ничего странного. Бизибокс — это про компактность, а не про удобство или еще что.

Я не вполне уловил, что́ мешает отлаживать на полноценном Баше.

Zmicier ★★★★★
()
Ответ на: комментарий от Xenius

Кстати я прочитал описание BASH_LINENO и BASH_SOURCE и не совсем понял, как это использовать для дебага

В ash есть LINENO, выводите её в отладочнном echo. Ах да, в busybox (d)ash зачем-то стали вносить свои кривые правки без отправки оригинальному автору, забив на синхронизацию с оригиналом, где с $LINENO и пошли большие изменения. Так что можете взять мой busybox, там ash синхронизирован.

vodz ★★★★★
()
Ответ на: комментарий от Zmicier

Кстати я прочитал описание BASH_LINENO и BASH_SOURCE и не совсем понял, как это использовать для дебага

На убунте примерно так. Добавляем в начало:

set -x
PS4='+${BASH_SOURCE}:${LINENO}: '

И дальше пошел код. И после этого оно печатает имя файла, номер строки и строку, которую исполняет. Если PS4 оставить по умолчанию, то оно просто печатает строку (так умеет и busybox). Для маленьких скриптов это ок, но если там много чужого кода - очень сложно отслеживать ветвления. Я бы сказал - нереально.

что́ мешает отлаживать на полноценном Баше

Теоретически такой вариант есть. Для этого надо запихнуть баш в initrd, причем со всеми внешними программами и либами, которые им нужны. И даже я так делал, и даже оно как-то работало, только тут свои неудобства - если забыл либу для какой-то проги, то все, хана. А скриптов там много, и какие там они проги запускают я не знаю, и какие им либы нужны - тоже не знаю. Это надо проводить отдельную исследовательскую работу. На самом деле, нужны только те проги, которые реализованы в busybox и либы к ним. Ну то есть впринципе да, так делается: добавить весь /bin в initrd и сколько-то либ добавить... Просто это дополнительное геморойное место, поэтому этим путем идти не хотелось бы.

Так что можете взять мой busybox, там ash синхронизирован.

Круть! Но навскидку - не собралось. Каких-то либ не хватило, скорей всего, это не проблема, глубже смотреть буду вечером.

chabapok
() автор топика
Ответ на: комментарий от chabapok

Теоретически такой вариант есть. Для этого надо запихнуть баш в initrd

Зачем ?

anonymous
()
Ответ на: комментарий от chabapok

Для этого надо запихнуть баш в initrd, причем со всеми внешними программами и либами, которые им нужны.

Зачем? Можно только баш, к тому же можно собрать статически. А утилиты которые в busybox и так должны быть в виде симлинков или хардлинков в /bin и /sbin

Xenius ★★★★★
()
Ответ на: комментарий от Xenius

Зачем? Можно только баш, к тому же можно собрать статически. А утилиты которые в busybox

busybox с bash какой-то нонсенс получается. Но предыдущий комментатор намекал, что initrd != busybox в общем случае.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Бизибокс [за набор внешних утилит] с Башем [за оболочку] — какой-то нонсенс получается

Не усматриваю нонсенса.

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier

Не усматриваю нонсенса.

Это уже для меня не новость. Вот, например, http://www.opennet.ru/tips/3007_linux_remote_install_ssh_init_busybox_mount.s... Нормально, да? Я там объяснил почему.

Так и у вас. По объёму все остальные утилиты уже и смысла нет брать минимальные, добавка будет малозаметна. Мегабайтный bash + 35k /bin/init :)

vodz ★★★★★
()
Ответ на: комментарий от vodz

например

TL;DR.

По об’ему все остальные утилиты [пропущены слова, надо полагать «не превосходят чего-то-там»] — нет смысла брать минимальные...

Нет смысла делать то, в чем нет смысла — ну, например считать, что еще можно засунуть в оставшиеся килобайты, когда все, что вам нужно, влезло, а больше ничего не нужно.

Zmicier ★★★★★
()
Последнее исправление: Zmicier (всего исправлений: 1)
Ответ на: комментарий от Zmicier

например

TL;DR.

Там всё синенькое можно опустить.

что вам нужно, влезло, а больше ничего не нужно.

Либо мы считаем килобайты, то тогда их экономим, либо вообще всё не имеет смысла.

vodz ★★★★★
()
Ответ на: комментарий от Xenius

Зачем? Можно только баш, к тому же можно собрать статически.

Давайте сначала. Смотрите. Я хочу подкрутить и отладить скрипт init, он находится внутри initrd. Я не вижу способа использовать внешний по отношению initrd баш, поскольку в тот момент еще нету ничего примаунченного. Т.е., ко внешнему башу просто не долезешь.

В этом скрипте делается mkdir (и не только, но мы для конкретики возьмем ее) В busybox это внутреняя команда. В bash это внешняя команда. Значит нам надо скопировать mkdir в наш initrd. Но mkdir - это не единственное, что нам надо. Чтоб не париться, мы весь /bin тащим в initrd. Ладно, фиг с ним, когда отладим - все равно уберем. И тут мы выясняем, что у нас кернел паник. А чем дело? А мы забыли про либы. Ладно, делаем ldd mkdir и убеждаемся, что все либы скопированы. Нам надо для каждой либы тоже делать ldd, и подтягивать таким образом зависимости? Ладно, если надо - делаем. Но даже и без этого - все равно это отдельная задача, даже если ее решать отдельным скриптом.

Я когда-то это все делал, подтянул нужные для mkdir либы, и еще что-то. Уже не помню что. ldd-шнул несколько прожек выборочно - и только тогда оно заработало.

Собственно да, так можно. Но вопрос состоял в том, как бы этим всем не заниматься, но при этом достигнуть обозначенной цели. Может я вообще не тот путь избрал, и все это можно как-то проще.

chabapok
() автор топика
Ответ на: комментарий от chabapok

Я не вижу способа использовать внешний по отношению initrd баш

возьми qemu и используй вместо inird обычный виртуальный диск в файле - зачем запихивать что-то в initrd ?

anonymous
()

$BASH_SOURCE

Есть же $0. Да, это не полный аналог, но лучше чем ничего :)

joy4eg ★★★★★
()
Ответ на: комментарий от chabapok

Я не вижу способа использовать внешний по отношению initrd баш, поскольку в тот момент еще нету ничего примаунченного.

И не надо. Собери баш статически и засунь в initrd.

В busybox это внутреняя команда. В bash это внешняя команда.

Вот тут ты как раз немного ошибаешься. busybox — это multicall binary, в том числе там есть шелл (hush или ash в зависимости от опций при сборке) и есть тот же mkdir. При этом и /bin/sh и /bin/mkdir в initrd присутствуют и являются внешними командами для шелла. Только благодаря busybox им не обязательно быть отдельными файлами и они все являются просто жесткими или символьными ссылками на /bin/busybox.

Если ты просто добавишь во всю эту кухню /bin/bash (или собранный статически или вместе с библиотеками), то баш сможет использовать уже существующий /bin/mkdir который на самом деле является симлинком на busybox и ничего кроме баша тебе добавлять не надо.

Я ставил bash в OpenWRT на роутере пакетом (где был только bash) и всё работало и mkdir и прочее.

Xenius ★★★★★
()
Последнее исправление: Xenius (всего исправлений: 1)
Ответ на: комментарий от chabapok

Встроенные в ash, который встроен в busybox команды — это не то же самое, что команды, встроенные в сам busybox. Чтобы их посмотреть набери help:

Built-in commands:
------------------
. : [ [[ alias bg break cd chdir command continue echo eval exec
exit export false fg getopts hash help history jobs kill let
local printf pwd read readonly return set shift source test times
trap true type ulimit umask unalias unset wait

Xenius ★★★★★
()
Последнее исправление: Xenius (всего исправлений: 1)
Ответ на: комментарий от Xenius

При этом и /bin/sh и /bin/mkdir в initrd присутствуют и являются внешними командами для шелла.

Я понял. У меня символьных ссылок на них нет. Содержимое /bin в initrd выглядит так:

busybox  dd     eject   insmod    kmod      md5sum            nfsmount    poweroff  rsync     sh       wget
cpio     dmesg  fstype  ipconfig  loadkeys  mount             ntfs-3g     reboot    run-init  sleep
date     egrep  halt    kbd_mode  losetup   mount.util-linux  pivot_root  resume    setfont   udevadm

Соответственно, все что мне нужно - это просто сделать нужные симлинки и добавить bash. Причем, даже неособо важно, если туда попадут лишние симлинки.

В директории распакованного initrd:

#!/bin/bash

for f in /bin/*
do
  need=$(basename $f)
  if [ ! -f $need ]; then
    ln -s busybox $need
  fi
done

все, идея ясна. Пошел делать... отпишусь по результатам.

chabapok
() автор топика
Ответ на: комментарий от Xenius

Все получилось. Из неприятного. Некоторые прожки типа tr,cut,wc,sort и тд находятся в /usr/bin. Какое-то кол-во раз initrd из за этого нехотел работать, я добавлял линки руками, снова пробовал - оно ругалось на очередной файл. Потом я плюнул - и этим же скриптом добавил все из /usr/bin как линки на busybox. Там конечно 100500 абсолюно ненужных для initrd файлов, но не по одному же мне их добавлять...

В итоге оно загрузилось и выхлоп при помощи PS4 сделал такой, как хотелось. Так что, всем спасибо.

chabapok
() автор топика
Ответ на: комментарий от chabapok

добавил все из /usr/bin как линки на busybox

Боже мой! Перечень того, что в Бизибоксе есть, запросить не проще было?

$ busybox --help
BusyBox v1.22.1 (Debian 1:1.22.0-19+b1) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2012.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

	BusyBox is a multi-call binary that combines many common Unix
	utilities into a single executable.  Most people will create a
	link to busybox for each function they wish to use and BusyBox
	will act like whatever it was invoked as.

Currently defined functions:
	[, [[, acpid, adjtimex, ar, arp, arping, ash, awk, basename, blockdev, brctl, bunzip2, bzcat, bzip2, cal,
	cat, chgrp, chmod, chown, chroot, chvt, clear, cmp, cp, cpio, cttyhack, cut, date, dc, dd, deallocvt, depmod,
	devmem, df, diff, dirname, dmesg, dnsdomainname, dos2unix, du, dumpkmap, dumpleases, echo, egrep, env,
	expand, expr, false, fgrep, find, fold, free, freeramdisk, fstrim, ftpget, ftpput, getopt, getty, grep,
	groups, gunzip, gzip, halt, head, hexdump, hostid, hostname, httpd, hwclock, id, ifconfig, init, insmod,
	ionice, ip, ipcalc, kill, killall, klogd, last, less, ln, loadfont, loadkmap, logger, login, logname,
	logread, losetup, ls, lsmod, lzcat, lzma, lzop, lzopcat, md5sum, mdev, microcom, mkdir, mkfifo, mknod,
	mkswap, mktemp, modinfo, modprobe, more, mount, mt, mv, nameif, nc, netstat, nslookup, od, openvt, patch,
	pidof, ping, ping6, pivot_root, poweroff, printf, ps, pwd, rdate, readlink, realpath, reboot, renice, reset,
	rev, rm, rmdir, rmmod, route, rpm, rpm2cpio, run-parts, sed, seq, setkeycodes, setsid, sh, sha1sum,
	sha256sum, sha512sum, sleep, sort, start-stop-daemon, stat, strings, stty, swapoff, swapon, switch_root,
	sync, sysctl, syslogd, tac, tail, tar, taskset, tee, telnet, test, tftp, time, timeout, top, touch, tr,
	traceroute, traceroute6, true, tty, udhcpc, udhcpd, umount, uname, uncompress, unexpand, uniq, unix2dos,
	unlzma, unlzop, unxz, unzip, uptime, usleep, uudecode, uuencode, vconfig, vi, watch, watchdog, wc, wget,
	which, who, whoami, xargs, xz, xzcat, yes, zcat

Ну и соответственно for c in [ [[ acpid adjtimex ....

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier

Ага. Сделать /usr/bin симлинком на /bin ещё. Ну и запятые можно распарсить автоматом каким-нибудь там sed.

Xenius ★★★★★
()
Ответ на: комментарий от chabapok

Некоторые прожки типа tr,cut,wc,sort и тд находятся в /usr/bin

Можно просто сделать /usr/bin симлинком на /bin или наоборот.

А вообще странно как-то. Может ты распаковывал initramfs как-то неправильно что симлинки не создались?

Xenius ★★★★★
()
Ответ на: комментарий от Xenius

Можно просто сделать /usr/bin симлинком на /bin или наоборот.

Не надо так делать. init делает $PATH с этими путями, в том числе и для *sbin, а если очень хочется сэкономить на спичках, то сам busybox имеет опцию сборки без /usr. У ТСа просто линков не было на имеющиеся утилиты в busybox.

vodz ★★★★★
()
Ответ на: комментарий от Xenius

Почему не надо?

У вас появится возможность положить оригинальную программу вместо урезанной по стандартному пути. Да и вообще, смысл бы появился, если PATH начинался с /usr/bin, а потом уже /bin, так хоть какой-то выигрыш был бы.

vodz ★★★★★
()
Ответ на: комментарий от Zmicier

Боже мой! Перечень того, что в Бизибоксе есть, запросить не проще было?

Да знаю (теперь). Разумеется, надо было сделать так.

Сделать /usr/bin симлинком на /bin ещё

так в том то и дело этих прог не было ни в /bin ни в /usr/bin. Такой симлинк не спас бы.

Может ты распаковывал initramfs как-то неправильно что симлинки не создались?

Там после распаковки initrd был как минимум симлинк sh на busybox, И еще что-то было, всего там было 3 симлинка. Вряд ли я смог бы распаковать так, чтобы распаковалась только часть симлинков. Это такой initrd в убунте идет «из коробки».

chabapok
() автор топика
Ответ на: комментарий от vodz

не, такого нет. И в initrd лежит обрезаный busybox, он так не умеет. но это, кстати, правильный способ создания симлинков.

chabapok
() автор топика
Последнее исправление: chabapok (всего исправлений: 1)

Как отлаживать busybox-скрипты?

Так-же как и {ba/z/c}sh скрипты.

Всегда Ваш Капитан.

Весь остальной твой поток сознания про initrd & busybox и прочее неосиляторство я не хочу читать… Но в целом люди делают вот так

init_6 ★★★★★
()
Последнее исправление: init_6 (всего исправлений: 1)
Ответ на: комментарий от chabapok

не, такого нет. И в initrd лежит обрезаный busybox, он так не умеет.

Тогда можете смело писать им багрепорт. Ибо либо надо сразу иметь полный набор линков либо вызывать --install с поддержкой этой опции.

vodz ★★★★★
()
Ответ на: комментарий от init_6

На основе ссылки выше лично я для себя делал вот так вот в нём вот там вот то что я хочу видеть в /bin и /sbin моего initramfs. Сам init исправляется ручками под конкретную задачу. Собирается в кучу это дело обычным Makefile И да всё что будет жить в initramfs неплохо бы собирать статически но на самом деле это вовсе не обязательно.

init_6 ★★★★★
()
Ответ на: комментарий от init_6

init_6, да, хорошие ссылки. Не про то, конечно, но все равно полезно.

У меня там гораздо больше кода накручено. Это я поставил пакет live-boot и пытаюсь создать USB stick

А у вас там прям вообще все практически по военному просто.

chabapok
() автор топика
Ответ на: комментарий от chabapok

А у вас там прям вообще все практически по военному просто.

Оно если и не идеально… То близко к тому. И да из заявленного: luks, lvm2, mdadm, tuxonice, fsck работает всё и во всех сочетаниях но надо править init как и было сказано выше. А то что я не смог осилить это {упаковку/загрузку} модулей ядра из initramfs. Падает в панику ядро да и всё.

init_6 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.