LINUX.ORG.RU

Функции и аргументы - дофига вопросов!

 , ,


0

1

У меня тут несколько вопросов назрело. Аргументы в функцию передаются по тем же правилам, что и в скрипт? Что, если я передам пару аргументов в скрипт, а потом еще пару в функцию, и попытаюсь их обработать внутри функции как $1 и $2 - она проигнорирует 1й и 2й аргумент, переданный скрипту, и будет использовать только то, что передали конкретно функции?

Могу я использовать арифметические операции при обработке аргументов? Допустим я ввел 2 переменные с клавиатуры- a и b. Я использую их как аргументы при вызове функции.

myfunc $a $b

В самой функции я сравниваю $1 и $2 аргумент, и если они не равны, снова вызываю эту же функцию (т.е. саму себя, так вообще можно?), но уже с другими аргументами, нужно вычитание. Пример:

myfunc ${a-b} $b

Такая запись работает? Она вычитает b из a? Интерпретатор не жалуется, но программа ничего не вычисляет, более того, через несколько секунд вылетает ошибка.

Ошибка сегментирования (стек памяти сброшен на диск)

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

И вот еще что. После этой конструкции:

myfunc ${a-b} $b

Возможно, еще надо как-то сделать, чтобы измененный (после вычитания) 1й аргумент еще где-то/как-то сохранился, но я не пойму как. Я просто запускаю функцию в этом виде и жду результата, но такое ощущение что я должен написать что-то еще, т.е. грубо говоря пересохранить новое «a». Но т.к. это уже не просто переменная, а аргумент, че-то не пойму как это сделать. Т.е. походу сам рекурсивный вызов функции с измененными аргументами (вычитание) не сохраняет состояние измененных аргументов, и поэтому она крутится бесконечно...

И вообще, не помешал бы отладчик для баш-скриптов, как в этих новомодных редакторах вроде Visual Studio. Ну почему для баша такого нет? Чтоб на блюдечке да построчно показывало мне выполнение инструкций- я ведь даже не представляю что творит мой скрипт, когда он разрастается чуть дальше хелоу ворда… Ну вернее я пишу его со знанием дела, но он все-равно не работает, едрить его налево. Всунул пару отладочных echo, и чето ни разу не помогло…

shkolnik_2022
() автор топика

${a-b}

$((a-b))

снова вызываю эту же функцию (т.е. саму себя, так вообще можно?)

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

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

У меня тут несколько вопросов назрело. Аргументы в функцию передаются по тем же правилам, что и в скрипт? Что, если я передам пару аргументов в скрипт, а потом еще пару в функцию, и попытаюсь их обработать внутри функции как $1 и $2 - она проигнорирует 1й и 2й аргумент, переданный скрипту, и будет использовать только то, что передали конкретно функции?

Ну давай проверим.

$ cat test.sh
#!/bin/sh

myfunc()
{
    echo "myfunc args: '$0' '$1' '$2' '$3'"
}

echo "script args: '$0' '$1' '$2' '$3'"
myfunc "$2" "$1"

$ ./test.sh 1 2 3
script args: './test.sh' '1' '2' '3'
myfunc args: './test.sh' '2' '1' ''

Как видишь, $0 передаётся без изменений, остальные аргументы передаются так, как ожидается.

Могу я использовать арифметические операции при обработке аргументов?

Можешь, но не так, как ты написал. Чтобы использовать арифметику в sh, надо использовать программу expr, например expr $a - $b. Если ты хочешь использовать башизмы, есть более простой синтаксис: $((a - b)). А ${a-b} это фигня какая-то, я даже не знаю, что это означает.

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

Я сначала хотел так. Но вот так:

${a-b}

Редактор nano подсвечивает эту конструкцию красным целиком - как обычная подстановка аргумента.

А как ты предложил, происходит вообще странная фигня.

Однобуквенный аргумент подсвечивается красным: $a

Аргумент с вычитанием $[a-b] - все зеленое, кроме «a» (оно почему-то серое).

А если эта конструкция с вычитанием еще и на месте 2го аргумента стоит, то обе буквы будут серыми. Не понимаю что за фигня.

И все-таки нет, от ошибки сегментирования квадратные скобочки не спасли.

А почему не { } скобки? Видел один раз в примерах такое.

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

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

По идее она не должна быть очень глубокой. Там всего 3-5 вызовов функции самой себя. Но повторю последнее предположение, что я не пойму надо ли сохранять состояние аргумента после вычитания и как. И вообще проверить бы, что там с ним происходит в этот момент. Там выше подсказали какой-то bash -x, надо посмотреть.

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

Ты корректность конструкций по подсветке синтаксиса определяешь? Не надо так.

А почему не { } скобки? Видел один раз в примерах такое.

На, почитай.

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

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

Пробовал после рекурсивного вызова функции:

myfunc $((a-b)) $b

Добавлять, например, такое, чтобы сохранить новое значения 1го аргумента:

a=$1

И вообще ничего не поменялось.

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

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

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

Ты корректность конструкций по подсветке синтаксиса определяешь? Не надо так.

Думал у nano с этим проблем нет. Обычно красным он подсвечивал аргументы целиком, но фиг поймешь логику подсветки. За ссылку спасибо!

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

Хотел сначала конкретней написать что мне нужно, и даже код показать, но чую придет кэп и решит все за меня, тем более задача простейшая (по меркам не-новичка). Поэтому описал только моменты, которые были непонятны. Если решить не смогу, может и выложу целиком. Пока пытаюсь понять отладчик…

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

значения не меняются, значит как-то надо сохранять

Ты хочешь менять переменные a и b? Типа такого: $((a-=b))?

Короче, почитай всё-таки мануал.

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

Ну да, надо чтобы аргумент после вычитания сохранял свое новое состояние. Думаю a=$1 я правильно использовал. Но пока я не могу совладать с отладчиком, там целая простыня вылезает…

shkolnik_2022
() автор топика

Народ, выручай!

bash -x myscript.sh

Выдает километровую простыню (вплоть до ошибки сегментирования), а мне надо скажем, первые 50 строк вывода прочитать, которые не влезают в консоль! Начало вывода где-то теряется из-за размера лога...

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

Почитай уже Никлауса Вирта и прекрати тут нас информировать о том, как ты познаешь мир.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от Legioner

Если ты хочешь использовать башизмы, есть более простой синтаксис: $((a - b))

Не выдумывайте. Это не башизм-ы, это изобрели в оригинальном sh, лет так 40 назад и уже лет так 30 как застандартизировано в POSIX.

vodz ★★★★★
()

Короче, я разобрался, рекурсивный вызов функции не работает, т.к. после:

myfunc $((a-b)) $b

У меня нигде не сохраняется новое значение измененного аргумента (после вычитания), и я никак не могу получить нужный результат. Пытался сохранять новый аргумент так a=$1 (сразу после вызова рекурсивной функции), но отладчик показывает, что до этого присваивания даже никогда не доходит, т.е. функция гоняет саму себя, постоянно подсовывая изначальные аргументы, которые я ввел с клавиатуры...

А нельзя сделать вычитание с присвоением как-нибудь прямо при передаче аргумента?

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

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

shkolnik_2022
() автор топика

Разобрался! Главное было найти правильное место в цикле для присваивания, и результат получился нужным.

shkolnik_2022
() автор топика

bash -x вообще мощь! Без него бы хрен сообразил где ошибка. Вернее догадка была, но проверить было нереально.

А подскажите, вот тут пишут что баш не имеет отладчика.

https://www.opennet.ru/docs/RUS/bash_scripting_guide/c13099.html

А bash -x это что тогда, как не отладка?

shkolnik_2022
() автор топика

В самой функции я сравниваю $1 и $2 аргумент, и если они не равны, снова вызываю эту же функцию (т.е. саму себя, так вообще можно?), но уже с другими аргументами, нужно вычитание.

Это же алгоритм Евклида :) Но зачем его писать на баше?

Crocodoom ★★★★★
()

Функции и аргументы - дофига вопросов!

man bash — дофига ответов!

P.S. Дальше заголовка, разумеется, не читал.

gremlin_the_red ★★★★★
()

несколько вопросов назрело

Когда возникают вопросы по БАШ, то обращаюсь к ABS. Там масса конкретных примеров.

Всунул пару отладочных echo, и чето ни разу не помогло…

Значит не туда всунул. Способ простой и эффективный, как топор. Освоишь. Например:

echo «debug: [$0 $@] $a»>>/home/user/debug.log; exit 0

Где:

debug - для индикации места, где сработал бряк.

[…] - для ориентации на случай если переменные «пустые».

debug.log - перенаправление в лог-файл.

exit - бряк.

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