2

Thanks for this Post it helped me a bit

returning value from called function in shell script

I have written a code like below :

File.c

i = system("/home/ubuntu/Documents/Flash_Desk_App/Project/test.sh -c");
printf("SH = %x",i);

test.sh

ONE=1   
echo " Hello world "        
clean()
    {        
    CLEAN_FLAG=1
    echo $ONE
    return "$ONE"    
    }

option="${1}"
case ${option} in
      -c) 
echo "Cleaning"
clean
;;  
    *) echo "Usage"
usage
;;
esac

but when i execute my ./a.out this is the output

Hello world 
Cleaning
1
SH = 0

IT ALWAYS PRINTS 0. CAN SOME ONE GUIDE ME IN SOLVING THIS. i WANT TO COLLECT THE VARIABLE VALUE RETURN BY SHELL IN MY C CODE.

Community
  • 1
  • 1
user2598064
  • 157
  • 1
  • 13
  • this is for some application.... ok i will remove the tag LDD.. any person from the lDD community can be aware of this..as we ahve lot to do with scripts – user2598064 Apr 11 '14 at 12:07

3 Answers3

3

It is because the script is exiting with return code 0 (success). The exit status of a command is updated for every command that is executed. If you want to exit with the status of the clean command, you will need to do the following in your script:

EDIT - including full code to see the exact changes:

ONE=1   
echo " Hello world "  

# Initialize RC
rc=0

clean()
    {        
    CLEAN_FLAG=1
    echo $ONE
    return "$ONE"    
    }

option="${1}"
case ${option} in
      -c) 
echo "Cleaning"

# Run the clean command and capture the return code
clean
rc=$?

;;  
    *) echo "Usage"
usage
;;
esac

# Return the captured return code as our script's exit status.
exit $rc

Then it should work.

NOTE: you might get a different value in the C code (like 127) instead of 1. There is a strange mapping that takes place between shell exit codes and the return value of system calls from C.

An example executing this script from the bash shell:

$ ./test.sh -c
 Hello world 
Cleaning
1
$ echo $?
1

Thus, it can be executed as a system call from C and you can get the return code.

Trenin
  • 2,041
  • 1
  • 14
  • 20
  • thanks for your answer..but i need the return value from function..for which this might not be the soultion... i need the contents of $ONE in script – user2598064 Apr 11 '14 at 12:05
  • @user2598064 This should work for exactly that. Inside the script, you need to get the return code of the the `clean` function right after it is called. I've stored it in a variable `rc`. then, the rest of your script executes, and at the end, we exit test.sh with that return code. This makes the return code of the `clean` function available to external callers - like your C program! – Trenin Apr 11 '14 at 12:10
  • @user2598064 A good way to try this kind of thing out is to execute a shell command and then `echo $?`. It will display the exit status (or return code) of the command. Run your original `test.sh` from the command prompt and see what the return code is (should be `0`). Then make the changes I suggest and run it again. It should now have a return code of `1`. – Trenin Apr 11 '14 at 12:11
  • What type of shell are you using? – Trenin Apr 11 '14 at 12:15
  • i think you have mentioned it wrongly as ?$ which should be $? – user2598064 Apr 11 '14 at 12:15
  • i printed the value echo $? its 0 – user2598064 Apr 11 '14 at 12:16
  • @user2598064 Did I? must have been in the previous edit. Sorry about that! – Trenin Apr 11 '14 at 12:16
  • i have done the changes in same manner.. doesnt work..always pritns "0" – user2598064 Apr 11 '14 at 12:20
  • See my edits to the answer. I copied the code I gave exactly as written into a file called test.sh. I chmoded it to 700, and ran it it using the bash shell. If you aren't getting the same results, you must have copied something incorrectly. – Trenin Apr 11 '14 at 12:22
  • i get the same output on executing the script independently as you get. but the return value printed in c is always zero – user2598064 Apr 11 '14 at 12:25
  • $? is always zero.. if you execute the script independently or through c call – user2598064 Apr 11 '14 at 12:28
  • @user2598064 Not sure what to say - when I run it, it is 1, just like I posted in the answer. What OS distribution do you have? What version? What shell are you running? All these can play a role, so it is best to mention them. Perhaps you can add a `#!/bin/bash` to the top of your script to ensure it is bash? I am running Ubuntu 13.10 and using bash as my shell. – Trenin Apr 11 '14 at 14:06
  • if you try printing the value of $rc just above exit in test.h. you will find it is Zero – user2598064 Apr 14 '14 at 07:39
  • SORRY FOR THE TROUBLE THIS WORKED WITH THE MACRO WEXITSTATUS. I was collecting the status in unsigned char which resulted in issue.... thanks alot for your interest – user2598064 Apr 14 '14 at 08:35
  • @user2598064 The macro wasn't used when you executed the script independently, so why were you not getting 1 when running the script directly from the shell? – Trenin Apr 14 '14 at 12:33
  • hi, i still dont get the 1 when i do echo ,can you tell me how can i pass the path argument from c code ... for e:g if i want to pass "/usr/bin/executable.bin" to shell script – user2598064 Apr 14 '14 at 12:52
  • Arguments to shell scripts are read by the script with `$1, $2`, etc. Just pass them on the command line. – Trenin Apr 14 '14 at 12:56
1

Besides the fact mentioned in Trenin's answer, apply the macro WEXITSTATUS to the value returned by system() to get the value returned by the command it executed.

From man 3 system:

RETURN VALUE

The value returned is -1 on error (e.g., fork(2) failed), and the return status of the command otherwise. This latter return status is in the format specified in wait(2). Thus, the exit code of the command will be WEXITSTATUS(status). In case /bin/sh could not be executed, the exit status will be that of a command that does exit(127).

The lesson learned here is: RTFM

Community
  • 1
  • 1
alk
  • 69,737
  • 10
  • 105
  • 255
0

The above answers should all do. Better to make sure you get the right return value with your bash script first.

# ./test.sh -c

# echo $?
1

(You can allways make changes to ONE=1) Then test it with your C code.. (don't forget to pass the return value from the (system) call to the WEXITSTATUS(i)) to get the right return value.

{
    i = system("/home/ubuntu/Documents/Flash_Desk_App/Project/test.sh -c");
    i = WEXITSTATUS(i);
    printf("SH = %x",i);
}
Ari
  • 92
  • 5
  • i think you people have not tried the complete loop for testing. i admire the return value from clean function is printed as one. but it is not printed as one in c program – user2598064 Apr 14 '14 at 07:21
  • if you try printing the value of $rc just above exit in test.h. you will find it is Zero. – user2598064 Apr 14 '14 at 07:22
  • SORRY FOR THE TROUBLE THIS WORKED WITH THE MACRO WEXITSTATUS. I was collecting the status in unsigned char which resulted in issue.... thanks alot for your interest – user2598064 Apr 14 '14 at 08:36