Find the answer to your Linux question:
Results 1 to 8 of 8
I need to pass variable from sc1.sh to sc2.sh and update the value of the passed variable in sc2.sh and then return the updated value of the variable from sc2.sh ...
  1. #1
    Just Joined!
    Join Date
    Jun 2010
    Posts
    9

    passing variable between scripts

    I need to pass variable from sc1.sh to sc2.sh and update the value of the passed variable in sc2.sh and then return the updated value of the variable from sc2.sh to sc1.sh.
    Last edited by ashishmann; 03-09-2011 at 09:42 AM. Reason: misprinting

  2. #2
    Just Joined!
    Join Date
    Mar 2007
    Location
    Bogotá, Colombia
    Posts
    39
    There are two possible scenarios:

    First: The variable you want to update is an integer value

    for doing this you need to return an integer value, in sc2.sh:

    Code:
    #!/bin/bash
    
    YOURVARIABLE=$1
    
    ... <Do whatever it is you need to do>
    
    return $YOURVARIABLE
    on sc1.sh you need to call sc2.sh inserting your variable as an argument and then retrieving the value as the return state of sc2.sh, like this

    Code:
    #!/bin/bash
    
    ... <Whatever it is your doing in sc1.sh>
    
    sh sc2.sh $YOURVARIABLE
    YOURVARIABLE=$?
    
    ... <Continue doing what you were doing>
    The second scenario, and probably a more generic one, is pretty much the same. The only difference is that you must not return any value in sc2.sh, but you need to end your script with an 'echo' of your variable:

    Code:
    #!/bin/bash
    
    YOURVARIABLE=$1
    
    ... <Do whatever it is you need to do>
    
     echo $YOURVARIABLE
    As for sc1.sh, you need to execute your second script like this to get the 'echo' you did in sc2.sh:

    Code:
    YOURVARIABLE=$(sh sc2.sh $YOURVARIABLE)
    You can also try to do this with functions instead of two different scripts.

  3. #3
    Linux Newbie
    Join Date
    Nov 2008
    Location
    Tokyo, Japan
    Posts
    243

    Correction

    LSalab, please check to make sure your code runs correctly before posting it as a reply.
    This will FAIL:
    Quote Originally Posted by LSalab View Post
    There are two possible scenarios: First: The variable you want to update is an integer value for doing this you need to return an integer value, in sc2.sh:
    Code:
    #!/bin/bash
    YOURVARIABLE=$1
    ... <Do whatever it is you need to do>
    return $YOURVARIABLE
    on sc1.sh you need to call sc2.sh inserting your variable as an argument and then retrieving the value as the return state of sc2.sh, like this
    You mean to say "exit". The "return" keyword can only be used within functions, and can only return numeric values -- return 0 to indicate success, return any other number to indicate a problem. Likewise, to exit a sub-script, "exit 0" to indicate success, anything else to indicate failure.

    You must call "exit" with a number between 0 and 255. Passing anything else will force the value to 255, so you cannot pass strings.

    When a child process calls "exit", the parent shell process will have its "$?" variable set to the value passed by the child "exit" command. You MUST NOT pass variable values this way. The exit value must ONLY used to indicate the success or failure status of the process.

  4. #4
    Linux Newbie
    Join Date
    Nov 2008
    Location
    Tokyo, Japan
    Posts
    243
    Quote Originally Posted by ashishmann View Post
    I need to pass variable from sc1.sh to sc2.sh and update the value of the passed variable in sc2.sh and then return the updated value of the variable from sc2.sh to sc1.sh.
    You will need to be much more specific. Is "sc2.sh" called from within "sc1.sh"?

    When you execute a sub-script, like this: ./sc2.sh or like this: bash sc2.sh, you can pass variables to sc2.sh using the "export" directive, but you cannot pass variables back to the calling context.

    You can, however, execute a script of the same language using the "." operator or the "source" directive.
    Code:
    #sc1.sh
    MY_VARIABLE="Set by SC1"
    Code:
    #sc2.sh
    MY_VARIABLE="Set by SC2"
    Code:
    MY_VARIABLE='Hello, world!'
    echo $MY_VARIABLE
    # outputs: Hello, world!
    
    . sc1.sh
    echo $MY_VARIABLE
    #outputs: "Set by SC1"
    
    source sc2.sh
    echo $MY_VARIABLE
    #outputs: "Set by SC2"
    The reason this works is because sub-processes can inherit variables from their parent processes, but cannot set environment variables for their parent. However, the "." operator does not create a sub-process, it simply executes the code in the file as though it were copy-pasted into the script that "called" it.

    For tasks that are more complex, you must make use of a database software instead, like SQLite -- that is the best way to make sure variables are passed between processes correctly.

  5. #5
    scm
    scm is offline
    Linux Engineer
    Join Date
    Feb 2005
    Posts
    1,044
    Quote Originally Posted by ramin.honary View Post
    For tasks that are more complex, you must make use of a database software instead, like SQLite -- that is the best way to make sure variables are passed between processes correctly.
    Or just use temporary files - setting up a database for passing a few items of data can be overkill.

  6. #6
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
    Posts
    1,117
    Hi.

    Observations:

    The return may be used if a script is sourced. I don't know why that's part of the design, but it could be used.

    The most-often used method for simple tasks that I have seen (and that I use in my scripts) is capturing standard output ( STDOUT ) with the mechanism provided by the shell, back-tics (old), and parentheses (modern). For somewhat more complex tasks I would use temporary files as scm suggested.

    For example in script "s0" that uses other scripts "s1" and "s2":
    Code:
    #!/usr/bin/env bash
    
    # @(#) s0	Demonstrate call, source, return of scripts.
    
    # Utility functions: print-as-echo, print-line-with-visual-space.
    pe() { for i;do printf "%s" "$i";done; printf "\n"; }
    pl() { pe;pe "-----" ;pe "$*"; }
    
    pl " Script s2:"
    cat s2
    
    pl " Script s1:"
    cat s1
    
    pl " Call s2 directly (uses return), expect failure:"
    ./s2
    
    pl " source s2, expect success:"
    . ./s2
    
    pl " Set variable to STDOUT from script (old form, back-tics):"
    a=1
    echo " a before is \"$a\""
    a=`./s1 $a`
    echo " a after  is \"$a\""
    
    pl " Set variable to STDOUT from script (modern form, parentheses):"
    a=9
    echo " a before is \"$a\""
    a=$( ./s1 $a )
    echo " a after  is \"$a\""
    
    exit 0
    producing:
    Code:
    % ./s0
    
    -----
     Script s2:
    #!/usr/bin/env bash
    
    # @(#) s2	Demonstrate return in main script (must be sourced).
    
    # Utility functions: print-as-echo, print-line-with-visual-space.
    pe() { for i;do printf "%s" "$i";done; printf "\n"; }
    pl() { pe;pe "-----" ;pe "$*"; }
    
    # Could use "echo", but printf is more likely to be well-behaved
    # among shells, and is far more versatile.
    
    pe " Hello, world."
    
    return 0
    
    -----
     Script s1:
    #!/usr/bin/env bash
    
    # @(#) s1	Demonstrate increase of expected integer parameter.
    
    arg=$1
    x=$( expr $arg + 1 )
    # Could also be:
    # (( x=arg++ ))
    printf "$x\n"
    
    exit 0
    
    -----
     Call s2 directly (uses return), expect failure:
     Hello, world.
    ./s2: line 14: return: can only `return' from a function or sourced script
    
    -----
     source s2, expect success:
     Hello, world.
    
    -----
     Set variable to STDOUT from script (old form, back-tics):
     a before is "1"
     a after  is "2"
    
    -----
     Set variable to STDOUT from script (modern form, parentheses):
     a before is "9"
     a after  is "10"
    The man pages for the shells are long, but contain the information one usually needs. Experimentation is often the best teacher.

    Best wishes ... cheers, drl
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

  7. #7
    Just Joined!
    Join Date
    Feb 2005
    Location
    Boulder, Colorado, USA
    Posts
    7
    Why do you need two scripts to do this? Wouldn't it be easier to make the second "script" a function in the first script and just call it as necessary?

  8. #8
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
    Posts
    1,117
    Hi, PTrenholme.

    If you are asking me, then I agree with you that a function would be best -- assuming a modern shell. There are some other issues with functions if one desires a library of them, but functions local to a script should be straight-forward.

    I don't know the background of the OP or the reason that the OP was asking a question, so I was trying to illuminate the situation concerning calling scripts, returns, etc ... cheers, drl
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...