LINUX.ORG.RU

Bash: парсинг параметров

 ,


0

2

Неужели за долгие долгие долгие... ГОДА. В баше так и не сделали нормальный парсинг аргументов из КОРОБКИ? Неужели нужно вечно страдать, втыкать в каждый файлик лапшу из ИИ гугла одну и ту же?

while [[ "$#" -gt 0 ]]; do
    case "$1" in
        -o|--output)
            output_file="$2"
            shift # Consume the argument's value
            ;;
        -v|--verbose)
            verbose=true
            ;;
        -i|--input)
            input_value="$2"
            shift # Consume the argument's value
            ;;
        *)
            echo "Unknown parameter: $1"
            exit 1
            ;;
    esac
    shift # Consume the current argument (flag or unknown)
done


с этими корявыми закорючками, которые никогда не запомнишь?

Вот это вообще что такое?

while [[ "$#" -gt 0 ]]; do


Я до сих пор не могу это понять интуитивно. Кто это вообще придумывал такой синтаксис? Что он ел? Что пил?

;;

Зачем делать 2 точки с запятой?

★★★★

Последнее исправление: gobot (всего исправлений: 2)

В rc это пишется короче, но не уверен, что ТС понравится.

while (! ~ $#* 0) switch ($1) {
case -o --output
	outputfile = $2
	* = $*(3-)
case -v --verbose
	verbose = 1
	* = $*(2-)
case -i --input
	input = $2
	* = $*(3-)
case *
	echo >[1=2] unexpected argument: $1
	exit args
}
kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 2)

ИИ гугла

недавно впервые решил воспользоваться ии и попросил его написать однострок для извлечения времени из uptime и оно мне такую дичь стало предлагать - ни один вариант оказался не рабочим и тогда пришлось привычно гуглить, лазить по сайтам - пока не нашлось то самое что искал uptime | awk -F, '{sub(".*up ",x,$1);print $1}' научите уже этот ии просто гуглить, а не выдумывать самому непонятно что.

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

Я не спрашивал манов и доков, я пор от что не интуитивно, все эти две точки ;; потом do надо писать, "-gt 0" вместо просто «>». Жуткая смесь чего-то с чем-то

ну и вообще, почему нет парсинга номрального?

Охота как то

ARGS = parse()
echo $ARGS[«from»]
echo $ARGS[«to»]

bash script.sh --from my --to xer

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

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

Ну getopts те же яйца в профиль, тот же самый цикл с этими точками закорючками

Цикл с точками и закорючками — это bash. Не нравится bash — берёшь любой другой: питон, перл, фиш, да хоть (не)любимую сишечку и пишешь. Из-за чего истерика-то?

ну и вообще, почему нет парсинга номрального?

Потому что нормальность у каждого своя.

debugger ★★★★★
()

Очевидно - пиши свои скрипты на перле/питоне/другом языке, если не осиляешь баш. Да и скрипты начинают разрастаться/усложняться - замена Bash на что-либо еще это не выбор, это данность. Поработай некоторое время с массивами в Bash и почувствуй как хорошо сделаны массивы в более других языках :-)

Pinkbyte ★★★★★
()

Баш нельзя улучшать, он лишь станет еще закорючливее и страшнее. Его надо хоронить, но Поттеринг пока занят.

thesis ★★★★★
()

Ты за ГОДЫ так и не написал себе библиотеку функций для баша. Bash – это в первую очередь командный интерпретатор, оболочка, а уже потом средство малой автоматизации ;)

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

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

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

сейчас бы сравнивать язык из 60-х с современными. тогда всякие прологи и прочий ужас были, даже lisp считался языком программирования, а не набором смайлов

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

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

Ну вот возьми и напиши. Это ведь с дивана критиковать всё легко и просто.

bash script.sh –from my –to xer

Башу — сто лет в обед, а ассоциативные массивы появились в нём совсем недавно. Плюс ассоциативные массивы наверняка считаются башизмом и многие не будут использовать их, потому что это не будет работать в даше.

А если чуть усложнить пример? Что делать, если пользователь не укажет опцию? Или укажет два раза? Запоминать в ассоциативном массиве первое значение или последнее? Или накапливать все указанные? Упс, в баше структуры данных примитивные, массив не может быть элементом другого массива…

А в случае с циклом у тебя полный контроль и совместимость с древними версиями баша или дашем.

что не интуитивно, все эти две точки ;;

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

«-gt 0» вместо просто «>».

Это оттого, что ты никогда не читал манов. Если б читал, то знал бы, что писать > вместо -gt можно:

while (( $# > O )); do 
    ...
done

Написание программ для компьютера всегда было точным делом — любая точка или запятая важна, = (или :=, если кто помнит) — не то же самое, что == (=). Откуда ты такой вылез с детскими претензиями «;; неинтуитивно»?

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

надо писать, «-gt 0» вместо просто «>»

Видимо для тех, кто из старой школы и чтобы не переучиваться. Надо освоить [[..]] и ((..)) — сразу полегчает.

papin-aziat ★★★★★
()
Последнее исправление: papin-aziat (всего исправлений: 1)

В баше так и не сделали нормальный парсинг аргументов из КОРОБКИ? Зачем делать 2 точки с запятой?

Так вопрос про парсинг аргументов, или про синтаксис Bash?

Если про парсинг аргументов, то он good enough. Если нужно что-то более сложное, то вероятней всего нужно смотреть в сторону argparse или сlick в Python.

Если про синтаксис bash, то он достаточно эффективен для тех задач, для которых bash предназначен. Да, он немного непривычен, но это только потому, что bash (а точнее sh) разрабатывался во времена, когда сформировавшихся практик ещё не было. Предлагаю простить дедушку.

Kroz ★★★★★
()

Я понимаю, какую боль ты хочешь высказать.

Да, так и не сделали. Да, он всё ещё по умолчанию везде, за счёт чего придётся страдать.

Но у этого нет никакого решения, кроме как переходить на альтернативные оболочки (fish, nushell, прости хоспаде pwsh или даже xonsh) или писать уже на python. Тем более, что нейронка по запросу сгенерит каркас, как пить дать. Не нужно даже с нуля делать.

Или перепишет уже имеющиеся скрипты. Пусть и не идеально, но я пробовал, пойдёт.

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

я пор от что не интуитивно, все эти две точки ;;

Всё по нормам язык, это как в СИ в конструкции switch если не написать break, то выполнится отобранный этап и следующий за ним.

потом do надо писать, «-gt 0» вместо просто «>»

Таков синтаксис while, по сути при вызове getopts из массива аргументов, переданных скрипту при каждом проходе цикла удаляется аргумент, поэтому «-gt 0» - пока число аргументов больше нудя делай.

Жуткая смесь чего-то с чем-то

Читай ман или не используй bash.

ну и вообще, почему нет парсинга номрального?

Покажи мне скриптовый язык, в котором есть.

Ты можешь обращаться напрямую $1, $2, $3 и так далее.

А вообще - это принцип KISS, bash - интерпретатор и в первую очередь работает на возврате кодов ошибок вызова других программ и конструкций. Есть getopts и писать, думаю, что-то другое никто не будет.

Можешь сам написать и предложить для включения в основную кодовую базу, а потом поддерживать.

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

дней?

ты как ии…

чего?

чего набежало - если только минуты прошли занчит только минуты, если прошли часы то занчит часы и минуты, если уже дни прошли - заначит дни, часы и минуты, но у меня пока что до дней не доходило… данный однострок uptime | awk -F, '{sub(".*up ",x,$1);print $1}' если только минуты прошли извлекает так 1 min если часы так 1:01, ну а дней я еще не видел - так долго не работают компьютеры у меня, но ради эксперимента - можно попробовать.

amd_amd ★★★★★
()
Ответ на: комментарий от papin-aziat

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

При чём тут старая школа и «не переучиваться»? В первых версиях шелла команда test в соответствии с философией была внешней программой, шелл про неё ничего не знал. А в шелле знак > означает перенаправление вывода. поэтому test $# > 0 означает «перенаправить вывод команды test в файл с именем «0»». Отсюда и -gt, потому что каждый раз экранировать > неудобно, чревато ошибками, да и выглядит test $# \> 0 даже хуже чем test -gt 0. По этой же самой причине логические операции пишутся как -a и -o.

И только потом присобачили алиаc [ и сделали test встроенной командой (не знаю в каком порядке). Для обратной совместимости — чтобы не ломать уже написанные скрипты — синтаксис менять не стали, а не для того, что б «не переучиваться».

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

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

При чём тут старая школа и «не переучиваться»?

Можно совсем обойтись без test и [ современному башисту (если не читать чужой код), и даже без этих -gt, и тд. А это существенная экономия сил, чтобы быстрее начать писать скрипты, КМК.

А так-то да: логика развития, история, обратная совместимость — всё это надо и интересно, но потом 😊

papin-aziat ★★★★★
()

Ну вот в питоне написали argparse и чо? Для тривиальных случаев копипастишь boilerplate и подправляешь, КАК И В BASH. Для сложных случаев прыгаешь в присядку на костылях.

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

В принципе, то, что ты хочешь сделать, возможно. В rc так делают:

% flagfmt = 'o outfile,v,i infile'
% getflags -o hello -v -i world
flago=()
flagv=()
flagi=()
flago=(hello)
flagv=1
flagi=(world)
*=()
status=''

Выхлоп второй команды eval’ишь и получаешь опции в переменных. Ну и ещё простенький usage бесплатно. Почему этого нет баше — эволюционный багаж затрудняет гибкость и внедрение новых идей.

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

раз уж все равно втыкаешь из иигугла, то втыкай сразу на языке получше, зачем с башем то страдать? читать bash – боль, да

anonymous
()