How to define a function inside another function in Bash?
Use function defined with parenthesis () instead of braces <> :
f() ( g() < echo G >g ) # Ouputs `G` f # Command not found. g
Parenthesis functions are run in sub-shells, which have the same semantics of () vs <> , see also: Defining bash function body using parenthesis instead of braces
This cannot be used if you want to:
as those are lost in the created sub-shell.
TODO: without subshell
Bash has local variables feature which allows allow you to not have to create a subshell by using <> instead of () as in:
f() < local g=G echo $g ># Ouputs `G` f # Outputs empty line, `$g` is undefined. echo $g
- faster
- more convenient if you want to modify the parent shell in other aspects, e.g. with exit or modifying other globals
Unfortunately, there don’t seem to be an analogue for functions: Achieve Local Function
Nice. You can even pass local scope variables into g. Solves declaring global arrays in many cases? Example: function f( )( local var=$1; function g( )< echo $var; >; g; )
Function definitions in bash don’t work the way function definitions work in many other languages. In bash, a function definition is an executable command which defines the effect of a function (replacing any previous definition), in much the same way that a variable assignment command defines the value of a variable (replacing any previous definition). Perhaps this example will clarify what I mean:
$ outerfunc1() < >innerfunc() < echo "Running inner function #1"; >> echo "Running outer function #1" > > $ outerfunc2() < >innerfunc() < echo "Running inner function #2"; >> echo "Running outer function #2" > > $ $ # At this point, both outerfunc1 and outerfunc2 contain definitions of $ # innerfunc, but since neither has been executed yet, the definitions $ # haven't "happened". $ innerfunc -bash: innerfunc: command not found $ $ outerfunc1 Running outer function #1 $ # Now that outerfunc1 has executed, it has defined innerfunc: $ innerfunc Running inner function #1 $ $ outerfunc2 Running outer function #2 $ # Running outerfunc2 has redefined innerfunc: $ innerfunc Running inner function #2
Now, if you didn’t already know this, I’m pretty sure this wasn’t your reason for nesting function definitions. Which brings up the question: why are you nesting function definitions at all? Whatever effect you expected nested definitions to have, that’s not what they do in bash; so 1) unnest them and 2) find some other way to accomplish whatever you were trying to get the nesting to do for you.
How call a function inside another function
I’m working actually in a shell script to monitor a server’s resources. I have a function and I want to know: how can I call a second function inside the main one? Example:
funct mainfunct() < echo "Text to show here" **$secondfunct** >funct secondfunct()
2 Answers 2
mainfunct() < echo "Text to show here" $(secondfunct) >secondfunct() < echo commands here >mainfunct
Text to show here commands here
It should be noted that the $(secondfunct) here would expand to the words resulting from the split+glob operator applied to the standard output of secondfunct stripped of all trailing newline characters.
That’s not limited to bash and ksh . That would work in any POSIX shell (and some non POSIX ones like ash or zsh (though zsh wouldn’t do the glob part and not choke on NUL bytes))
@t7e you may need to open a separate question so that you can describe your environment, which is apparently different from this situation. Link to this Q&A for history or context if you like, but describe your setup and results and hopefully someone can spot the problem!
android@localhost:~/test$ cat fun.sh function myname < echo "my name is raja" >function call < myname >call
You must log in to answer this question.
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.12.43529
Linux is a registered trademark of Linus Torvalds. UNIX is a registered trademark of The Open Group.
This site is not affiliated with Linus Torvalds or The Open Group in any way.
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Использование функции внутри функции. Возможно ли в bash?
Сделал функцию для проверки статуса. И отдельно функции для кое-каких проверок по скрипту. Функции использую для того что бы можно было указать (промежуточный) код выхода через return и при этом продолжить скрипт (да и вообще удобно). А функция для проверки статуса как раз смотрит на промежуточный код выхода. И если код не тот, что ожидается — наращивает счетчик ошибки. Было бы здорово делать проверку прямо в функции, а не на выходе что бы какие-то дополнительные строки не испортили мой «заготовленный return». Возможно ли это как-то сделать? Т.к. гляжу, что вставлять функцию в функцию не вариант =( В общем виде это выглядит так:
check=0 function check-exit-stat() < if [ $? -ne $1 ] then check=`expr $check + 1` fi >function f1() < k=1 if [ $k -eq 0 ] then return 0 else return 1 fi #было бы хорошо тут поставить check-exit-stat 0 >т.к. если сделать так f1 check-exit-stat 0 exit $check
то возможно какие-то дополнительные записи после «fi» могут изменить статус выходной с того, что я указал при помощи return на любой другой. И это уже не годится. ps тупо делать наращивание счетчика в нужном месте не хотелось бы.
а как же вы хотите выполнять что либо внутри функции после return, ведь return как раз и предназначен для выхода из функции, всё что ниже просто не будет выполнятся.
1) Если же у вас там будет не return а некая команда которая возвращает код возврата($?) то можно просто загнать её в переменную и в конце функции вывести.
#!/usr/bin/bash check=0 check-exit-stat() < if [[ $!= $ ]] then ((check++)) fi > f1() < k=1 if [[ $== "0" ]] then ls # return 0 else blabla # return 127 fi N=$ check-exit-stat 0 $ return $ > f1 echo $? # . f1 echo $? # . echo check=$check exit $check
#!/usr/bin/bash check=0 check-exit-stat() < if [[ $!= $ ]] then ((check++)) fi return $ > f1() < k=1 if [[ $== "0" ]] then ls # return 0 else blabla # return 127 fi check-exit-stat 0 $ > f1 echo $? # . f1 echo $? # . echo check=$check exit $check
#!/usr/bin/bash check=0 check-exit-stat() < if [[ $!= $ ]] then ((check++)) fi return $ > f1() < k=1 if [[ $== "0" ]] then check-exit-stat 0 0 # return 0 else check-exit-stat 0 1 # return 1 fi > f1 echo $? # . f1 echo $? # . echo check=$check exit $check
В том то и дело, что мне надо явно указывать выходной статус. Да так что бы не прервать функцию либо скрипт целиком. Т.е. получается exit и return не подходят. В моём скрипте выполняется либо не выполняется условие по «if». Но с точки зрения bash там всё гладко и выход будет 0. А мне надо сделать не 0, если программа пойдет не по той ветке, по которой я хочу.
. Есть ли возможность указывать «выходной статус» и при этом не выходить.
Точнее что бы после нужной команды я мог указать любое значение для «$?» и при этом не сорвать скрипт / функцию? Или имеет смысл в таком случае просто вставить наращивание счетчика, когда не по той ветке идем. И потом некий check = 0 может вырасти до 1, 2 или 3 и выходной статус скрипта будет exit $check.
$? — это код завершения последний команды.
Любая команда, функция или скрипт должны когда либо завершаться. Поэтому явно или неявно return или exit присутствует в них.
www.opennet.ru/docs/RUS/bash_scripting_guide/c2105.html
> . Есть ли возможность указывать «выходной статус» и при этом не выходить.
ну вот простой пример:
blabla # несуществующая ф-я echo $? # возвращает код завершения 127 K=0 fn1() < blabla N=$if [[ $ == 127 ]] then K=1 else K=0 fi # . # здесь делаем то что нужно return $ > fn1 echo $?