LINUX.ORG.RU

Фичи, которых не хватает в sh

 , , , ,


0

2

Тема достойна толксов, а не девелопмента, но всё-таки запощу сюда.

Есть несколько функций, которые очень помогали бы мне при написании shell-скриптов.

  • Например, одна из них: singlestepping. В консоль выводится строчка, которая будет выполнена (с уже подставленными значениями переменных). Каждая следующая строчка выполняется только по нажатию клавиши. Можно прервать скрипт на каком-то конкретном месте, где вдруг перестал нравится его вывод или команда, выведенная в консоль.
  • Аналог «echo off», но с возможностью выбора stdout/stderr/both. Насколько я помню, в bat-скриптах этот «echo off» для одной строчки достигался дописыванием символа '@' в начало строки. Удобно было бы, нэ?
  • Чтобы не плодить ветвления, упростить логирование и сделать приятный вывод в консоль, хотелось бы иметь такую конструкцию:
    command1 && $?:0 command2; $?:1 command3; $?:* command4
    Это такой однострочный switch, который используется для обработки различных кодов возврата (теоретически, при существовании такой конструкции, можно придумать и другие сферы использования). Пример использования:
    ls && $?:0 echo "ok"; $?:1 echo "minor problems"; $?:2 echo "serious trouble"; $?:* echo "unknown error: $?"

Можно написать свою собственную несовместимую оболочку, можно сделать свой парсер такого кода, который будет преобразовывать эти конструкции в читаемый башем скрипт. Каких функций шелла не хватает вам для написания скриптов? Как обходитесь без них? Какие костыли предложите мне для лёгкой реализации вышеописанного?

★★★★★

которые очень помогали бы мне при написании shell-скриптов

сейчас тут будут набигать люди и говорить про архитектуру, но фиг там - я первый!

Хотелось бы посмотреть реальный пример, того что ты там так долго и безуспешно дебажил, что пришёл к таким революционным идеям

zolden ★★★★★
()

А я пишу скрипты на Ruby. И знаешь, там можно делать что угодно :)

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

Я вчера один маленький скрипт написал. Сегодня попытался добавить ему приятный вывод (перенаправить stdout и stderr в /dev/null и вывести строчки типа «Creating $SIZE disk image» или «Fail partitioning your image: fdisk returned code $?»), но это увеличивает его втрое, если не больше. Во мне проснулся Попов, которого всё не устраивает в существующем баше.
Вот сам скрипт mkdiskimage.sh (можете покидать в меня каловыми массами, ибо опыта у меня нет):

#!/bin/sh
# make sure that module 'loop' is loaded or compiled-in and max_part is >0
dd if=/dev/zero of=disk.img bs=1k count=61k
losetup /dev/loop0 disk.img
echo -e "o\nn\np\n1\n\n\na\n1\nw\n" | fdisk /dev/loop0
mke2fs -j /dev/loop0p1
tune2fs -c 0 -i 0 /dev/loop0p1
mount /dev/loop0p1 /mnt
mkdir /mnt/extlinux
cp /boot/* /mnt/extlinux/
dd if=/usr/lib/syslinux/mbr.bin of=/dev/loop0 bs=512 count=1
extlinux --install /mnt/extlinux

umount /mnt
losetup -d /dev/loop0
#VBoxManage internalcommands createrawvmdk -filename disk.vmdk -rawdisk disk.img

CYB3R ★★★★★
() автор топика

так а кто мешает case .. esac в одну строку написать?

к тому-же && как раз и проверяет код возврата, и если он ненулевой, вся эта твоя конструкция выполняться не будет

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

Так в том-то и дело, что в моём случае && делает выбор, не «выполнять или не в выполять», а «какой именно кусок выполнять», потому и не совместимо с sh. Я мог написать какой-нибудь несуществующий оператор, сути это не меняет.

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

С этим && нужно будет потом руками уточнять, какой именно ненулевой код возврата. Тут обсуждается синтаксический сахар для леса из &&, || и [ именно на случай, когда есть разница между разными ошибками.

x3al ★★★★★
()

и да, первое - set -x и set -e в начале скрипта зачастую оказывается достаточным.

второе - «exec 2> /dev/null» вместо 2 подставь номер нужного потока

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

Твои конструкции хороши, но громоздкие.
Про set -x и set -e не знал, «&> /dev/null» нужно после каждой команды дописывать, хочу для всего скрипта.

CYB3R ★★★★★
() автор топика

подобие single step

#!/bin/bash -x

trap " read ignore_this_string " DEBUG

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

Я знаю, но это не аналог «echo off».

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

Хотя, в целом мне нравится эта конструкция, буду её использовать.

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

Твои конструкции хороши, но громоздкие.

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

«&> /dev/null» нужно после каждой команды дописывать, хочу для всего скрипта.

exec не увидел, или впадло man bash прочитать?

ananas ★★★★★
()
Ответ на: комментарий от ananas
#! /bin/sh

exec 2> /dev/null

echo stdout > /dev/stdout
echo stderr > /dev/stderr
ananas ★★★★★
()
Ответ на: комментарий от vertexua

Пишу скрипты на Perl, таких проблем не испытывал

На лоре этот камент пишут даже когда обсуждаются скрипты вида echo «Hello, world»
Я в недоумении

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

для эстетов есть функции, при помощи которых такую конструкцию можно укоротить

Я сделал так:

#!/bin/sh

# make sure that module 'loop' is loaded or compiled-in and max_part is >0
# make sure you are root

FILENAME=disk.img
MOUNTPOINT=/mnt

function niceout {
	ERRCODE=$?
	if [ $ERRCODE != 0 ]
	then
		echo "! Error $1"
		exit $ERRCODE
	else
		echo "> Done $1"
	fi
}

dd if=/dev/zero of=$FILENAME bs=1k count=61k &>/dev/null
	niceout "creating $FILENAME"
losetup /dev/loop0 $FILENAME &>/dev/null
	niceout "creating loopback device"
echo -e "o\nn\np\n1\n\n\na\n1\nw\n" | fdisk /dev/loop0 &>/dev/null
	niceout "partitioning your image"
mke2fs -j /dev/loop0p1 &>/dev/null
	niceout "creating ext2 filesystem"
tune2fs -c 0 -i 0 /dev/loop0p1 &>/dev/null
	niceout "tuning filesystem"
mount /dev/loop0p1 $MOUNTPOINT &>/dev/null
	niceout "mounting your image"
mkdir $MOUNTPOINT/extlinux &>/dev/null
	niceout "creating directories"
dd if=/usr/lib/syslinux/mbr.bin of=/dev/loop0 bs=512 count=1 &>/dev/null
	niceout "installing mbr"
extlinux --install $MOUNTPOINT/extlinux &>/dev/null
	niceout "installing extlinux"
cp boot/* $MOUNTPOINT/extlinux/ &>/dev/null
	niceout "copying files to your image"

umount $MOUNTPOINT &>/dev/null
	niceout "unmounting your image"
losetup -d /dev/loop0 &>/dev/null
	niceout "detaching loopbackdevice"
echo "> Done successfully!"

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

Написание их на Perl позволяет не изучать bash-костыли в текстовике, которые называются скриптами, а не извращенным использованием простой консольки не по назначению

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

Быдлокод, быдлокод эвривер…
Почему у тебя сообщение вылезает после команды? А если команда повисла, как я пойму, какой это был этап? Лезть в шелл-скрипт? Ну и нафига мне в таком случае этот «интерфейс»?

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

Это (ба)ш, ничего не поделаешь.

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

И да, тебя один лишний форк возбудил?

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

Можно делать стандартно.

Creating ext2 filesystem... Done
Tuning filesystem... Done
Мounting your image...
Вот тут последняя команда повисла и понятно, что она делает. Спасибо, годная идея для TUI. А если заглянуть в код init-скриптов, можно позаимствовать цветные [ OK ] и [ FAIL ] с выравниванием.

CYB3R ★★★★★
() автор топика

Объектных пайпов же! Это все же огромный шаг вперед.
Были бы объектные потоки — не было бы советов «Не используйте имена файлов на кириллице и с пробелами», не было бы «Программа A представляет внутренние структуры в виде текста, а программа B переводит этот текст в свои внутренние структуры», не было бы «Парсим дату создания файла из вывода ls», не было бы «Добавьте к find -print0, а к xargs — -0» и прочей... беготни.

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

Только начали. Зато объекты — везде, как в оригинале.

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

Не используйте имена файлов на кириллице и с пробелами

Да хоть кандзи.

Программа A представляет внутренние структуры в виде текста, а программа B переводит этот текст в свои внутренние структуры

Пример что ле. Какие такие «внутренние структуры»?

Парсим дату создания файла из вывода ls
создания файла

Ох ю.

Добавьте к find -print0, а к xargs — -0

Это логично, если ты хочешь использовать в строке перевод строки, то нужно выбрать другой разделитель.

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