How to get the output of a shell function without forking a sub shell?

subshell
ksh spawn child process
ansible subshell
bash parallel subshell
shell script run command in subshell
bash run command not in subshell
zsh run in subshell
subshell vs subprocess

I have the following functions.

hello () {
        echo "Hello"
}
func () {
        hello
        echo "world"
}

If I don't want the output of the hello function to be printed but want to do something with it, I want to capture the output in some variable, Is the only possible way is to fork a subshell like below? Is it not an unnecessary creation of a new child process? Can this be optimized?

func () {
        local Var=$(hello)
        echo "${Var/e/E} world"
}

An ugly solution is to temporarily replace echo so that it sets a global variable, which you can access from your function:

func () {
  echo () {
    result="$@"
  }
  result=
  hello
  unset -f echo
  echo "Result is $result"
}

I agree it's nasty, but avoids the subshell.

Subshells, An ugly solution is to temporarily replace echo so that it sets a global variable, which you can access from your function: func () { echo () { result="$@" } result=  Translates a Shell namespace object's display name into an item identifier list and returns the attributes of the object. This function is the preferred method to convert a string to a PIDL. SHPathPrepareForWrite. Checks to see if the path exists.

How do I assign the output of a command to a variable without , #!/bin/bash # subshell-test.sh ( # Inside parentheses, and therefore a subshell least until terminated by a Ctl-C. exit $? # End of script (but will never get here). Overview of Unix Shell Functions: Shell Functions are used to specify the blocks of commands that may be repeatedly invoked at different stages of execution. The main advantages of using unix Shell Functions are to reuse the code and to test the code in a modular way. This tutorial will explain you all about Functions in Unix.

How about using a file descriptor and a Bash here string?

hello () {
    exec 3<<<"Hello"
}

func () {
    local Var
    exec 3>&-
    hello && read Var <&3
    echo "${Var/e/E} world"
    exec 3>&-
}

func

Is It Possible to Run Ls Command Without Fork?, Instead of using VAR_NAME=$() to run something in a subshell and assign it FUNCTION_OUTPUT=$(TEST hi); then echo Function return non-zero Just as the shell does, you have to read the data in, as is elsewhere suggested. I've already forked off a reader process to drain the pipe as necessary. The shell function performs the same function that backquotes (‘`’) perform in most shells: it does command expansion. This means that it takes as an argument a shell command and evaluates to the output of the command. The only processing make does on the result is to convert each newline (or carriage-return / newline pair) to a single

Not a bash answer: At least one shell, ksh optimises command substitution $( ... ) to not spawn a subshell for builtin commands. This can be useful when your script tends to perform a lot of these.

RFC: are non-forking subshells still worth having? · Issue #480 · att , If you want to execute command in current shell you have to put your in command For example, output redirection is managed by forking a subshell and in ksh/ bash attempts redirection without a subshell if possible, and (. A function will be called in a sub-shell if its output is piped somewhere else - that is, "myfunc 1 2 3 | tee out.log" will still say "x is 1" the second time around. This is because a new shell process is called to pipe myfunc().

Do you have the option of modifying the hello() function? If so, then give it an option to store the result in a variable:

#!/bin/bash

hello() {
  local text="hello"

  if [ ${#1} -ne 0 ]; then
    eval "${1}='${text}'"
  else
    echo "${text}"
  fi
}

func () {
  local var     # Scope extends to called functions.
  hello var
  echo "${var} world"
}

And a more compact version of hello():

hello() {
  local text="hello"
  [ ${#1} -ne 0 ]  && eval "${1}='${text}'" || echo "${text}"
}

Advanced Bash Shell Scripting Guide, To quote: "A subshell environment shall be created as a duplicate o. Unfortunately the code to handle input/output in subshells is too complicated And good luck finding a system without fork() younger than 20 years. Yes, it still has to fork to run subprocesses, even if they are shell functions, I believe. With a shell, users can type in commands and run programs on a Unix system. Basically, the main function a shell performs is to read in from the terminal what one types, run the commands, and show the output of the commands. What's so good about C Shell? The C shell was written by Bill Joy at the University of California at Berkeley.

Bash Reference Manual, Generally, a Bash builtin does not fork a subprocess when it executes within a script. Keywords have a special meaning to the shell, and indeed are the building blocks of the Be aware that echo `command` deletes any linefeeds that the output of A read without an associated variable assigns its input to the dedicated  Following works on windows 8.1, only a few simple changes from the VBA version linked in your question. REM ***** BASIC ***** Option Explicit Sub TestShellRun msgbox ShellRun("cmd.exe /c dir") End Sub Public Function ShellRun(sCmd As String) As String 'Run a shell command, returning the output as a string' Dim oShell As Object oShell = CreateObject("WScript.Shell") 'run command' Dim oExec As

How the shell executes commands, Redirections: A way to control where input and output go. An interactive shell without the interactive_comments option enabled does not allow Bash does not fork a subshell when redirecting into or out of a shell control  Shell Functions. As programs get longer and more complex, they become more difficult to design, code, and maintain. As with any large endeavor, it is often useful to break a single, large task into a series of smaller tasks.

[Linux](EN) Use multi processes(or threads) in shell script , When the shell has processed a command line and is left with a name that is not a the name of a function, or a second or subsequent command in a pipeline, it checks the Note that the output of a script that runs in a subshell is not automatically and interpreted directly by the current shell, without forking a sub- shell. In this chapter, we will discuss in detail about the Shell input/output redirections. Most Unix system commands take input from your terminal and send the resulting output back to your terminal. A command normally reads its input from the standard input, which happens to be your terminal by default.

Comments
  • It may be a creation of a subshell, but why is it a problem? Are you sure you're not optimizing prematurely?
  • @evilotto It may be a problem if function has side effects besides outputting to stdout: for example, changing variables.
  • I was also thinking on similar lines. I can replace all echo with Echo which does something like this. Will this make the shell functions faster?
  • Bash cryptics are practically endless,so4the~99% of us who even as long-time Bash coders NOT know-else-memomorize 100% of Bash docs, IN ENGLISH,"recode called fn so all its output is to a file-descriptor OTHER than stdout then manipulate that"(advanced!),per relevant OFFICIAL URLs FOR ADVANCED Bash ops gnu.org/software/bash/manual/html_node/… & gnu.org/software/bash/manual/html_node/… tho no find defined there quote(>&-) tho I do at tldp.org/LDP/abs/html/io-redirection.html#CFD
  • --Advanced! But is there a way (put in another answer here) to do this as the asker apparently asked(I really want,too): WITHOUT having to recode the function being called(so say in this case function remains hello(){ echo "Hello" })? -but still NOT creating a sub-shell(so then allowing the fn to do visible environment side-effects&more benefits),as called fn's stdout still redirected to this other file-descriptor. I made attempts such as my (internal)ID N6ZPBM where quote(exec hello 1>&3) (see my last cmt for official defs of these ops),but sadly these just give quote(3: Bad file descriptor).
  • bash appears to do the same
  • @LaurenceRenshaw In bash 4.4.12(1) on linux, echo $(echo foo) calls clone(), according to strace. That makes me think it does spawn a subshell. Do you have evidence that it doesn't?
  • It is a child process, but not a full sub-shell. The child does not call exec(), so does not incur the full overhead of a sub-shell, but it is still a separate process.
  • @AndrewVickers The ksh93 shell does not always fork for $( ... ), so no new process is created.
  • @Hank. Good to know for ksh, but apparently not the case for bash.
  • Actually, why even bother with -v. If there is a parameter, we can assume it is the variable name. Edited accordingly.
  • Fantastic! This works in a primitive BusyBox interpreter too.