1

I have

    #!/bin/sh

    func1()
    {
        echo "This is func1 from shell script"
    }

    func2()
    {
        echo "This is func2 from shell script"

    }

I want to call func1 and func2 from a C program. Can I do that ?

4
  • 1
    unless you're writing a loadable builtin, no. Commented Jan 25, 2013 at 5:45
  • @ormaaj How sure are you ? Commented Jan 25, 2013 at 5:46
  • @ormaaj Can you please elaborate about loadable builtin? Commented Jan 25, 2013 at 5:47
  • @abc Using and Writing Bash Dynamically Loadable Built-In Commands. You can write C code that accesses bash’s internal APIs, compile the C code into .sos, and load them into bash with the enable builtin. Commented Jan 25, 2013 at 6:27

3 Answers 3

7

This is unlikely to be a good idea, but I suppose you could write something like this:

if (! fork()) { // TODO fork can return -1 on error; should check for that
    execl("/bin/sh", "-c", ". FILE && func1", (char *)NULL);
    // TODO should check to make sure execlp successfully replaced the process
}

where FILE is the name of the .sh file that defines func1. The above will spawn a child process, and replace that child process with an instance of Bash (or whatever your shell is) with the arguments -c (meaning "the script to run is the next argument") and . FILE && func1 (which is the script; it means "run the commands in FILE, and if that succeeds, then run the command func1").

For more information:

Sign up to request clarification or add additional context in comments.

5 Comments

This also worked: system("source /home/abc/cpractice/test_functions ; func1 ; func2 "); Where is the documentation for the ; syntax used here?
@abc: ; is just a way of separating commands. You can use \n instead if you prefer. (The two are not completely equivalent in all cases, but they're equivalent in most cases.)
Note that if the script contains anything other than function declarations (i.e. if it's anything like a normal script), that will get executed as well. As @ruakh said, this is unlikely to be a good idea.
Probably better to use && instead of ;
@WilliamPursell: Good point, thanks; I've made that change now.
2

A little simpler than using fork / exec is the stdlib "system" command.

See man 3 system.

Assume your bash functions are in file "/tmp/scripts.sh" ...

system("bash -c \". /tmp/scripts.sh ; func1 ; func2\"");

Comments

0

If you want to recive the exit code of executing script, you should use system, else use vfork + exec*

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.