Find the answer to your Linux question:
Results 1 to 4 of 4
Hi, Read the following first. command group. (a=hello; echo $a) A listing of commands within parentheses starts a subshell. Variables inside parentheses, within the subshell, are not visible to the ...
  1. #1
    Linux Newbie Sangal-Arun's Avatar
    Join Date
    May 2006
    Location
    Gurgaon, India + Denver Colorado USA
    Posts
    101

    Cool Using (, ) or {, } braces in Bash behaviour

    Hi,

    Read the following first.

    command group.
    (a=hello; echo $a)

    A listing of commands within parentheses starts a subshell.
    Variables inside parentheses, within the subshell, are not visible to the rest of the script. The parent process, the script, cannot read variables created in the child process, the subshell.
    a=123
    ( a=321; )

    echo "a = $a" # a = 123
    # "a" within parentheses acts like a local variable.


    {}
    Block of code [curly brackets]. Also referred to as an inline group, this construct, in effect, creates an anonymous function (a function without a name). However, unlike in a "standard" function, the variables inside a code block remain visible to the remainder of the script.
    bash$ { local a;
    a=123; }
    bash: local: can only be used in a
    function

    a=123
    { a=321; }
    echo "a = $a" # a = 321 (value inside code block)

    # Thanks, S.C.
    Now, if you know the difference between (, ) (creates child/sub shell)
    and {, } (don't creates a child/sub shell and execute shell command statements in the same parent shell from where it's started) then why "c" variable in the following script is not getting c=AA.BB in the final echo statement.

    am i missing something?

    Script and its output:
    ===========
    [/efare1/Users/qabuild/aksutil/1] $ vim giga.aks.sh

    [/efare1/Users/qabuild/aksutil/1] $ chmod 700 giga.aks.sh

    [/efare1/Users/qabuild/aksutil/1] $ cat giga.aks.sh|grep -v ^$
    Code:
    #!/bin/bash
    a=A
    b=B
    c=$a.$b
    echo $c
    echo
    {
     echo giga1
     a=AA
     echo giga2
     b=BB
     echo giga3
     c=$a.$b
     echo $c
     echo
    } | tee -a giga.aks.out
    echo =======
    echo $c
    [/efare1/Users/qabuild/aksutil/1] $ ./giga.aks.sh
    A.B

    giga1
    giga2
    giga3
    AA.BB

    =======
    A.B

    [/efare1/Users/qabuild/aksutil/1] $ ll -tr|tail -2
    -rwx------ 1 qabuild denccefs 168 Sep 22 18:15 giga.aks.sh*
    -rw-rw-r-- 1 qabuild denccefs 25 Sep 22 18:15 giga.aks.out

    [/efare1/Users/qabuild/aksutil/1] $ cat giga.aks.out
    giga1
    giga2
    giga3
    AA.BB


    [/efare1/Users/qabuild/aksutil/1] $
    ===========
    Brgds,

    ARUN SANGAL
    SCM: 1- 720 251 9962
    Email: sangal.ak04@gmail.com
    Email: sangal_ak04@yahoo.com

  2. #2
    Linux Newbie tetsujin's Avatar
    Join Date
    Oct 2008
    Posts
    115
    I think that pipelining the output of a command has a similar effect to using parens around it - it creates a subshell in which variable assignments become local to that temporary environment.

    It doesn't strike me as particularly desirable behavior from a perspective of language design - but in terms of how the shell works (creating pipelines and forking processes to handle each end of the pipeline) it kind of makes sense.

  3. #3
    Linux Newbie Sangal-Arun's Avatar
    Join Date
    May 2006
    Location
    Gurgaon, India + Denver Colorado USA
    Posts
    101
    Or it's the SCOPE of { , } brackets. When i took the opening curly brace after #!/bin/bash line and the closing curly brace at the end of the line, i got the following.. which seems both tee and variable behaviour will work.

    [/efare1/Users/qabuild/aksutil/1] $ ./giga.aks.sh
    A.B

    giga1
    giga2
    giga3
    AA.BB

    =======
    AA.BB

    [/efare1/Users/qabuild/aksutil/1] $ cat ./giga.aks.out
    A.B

    giga1
    giga2
    giga3
    AA.BB

    =======
    AA.BB
    Brgds,

    ARUN SANGAL
    SCM: 1- 720 251 9962
    Email: sangal.ak04@gmail.com
    Email: sangal_ak04@yahoo.com

  4. #4
    Linux Newbie tetsujin's Avatar
    Join Date
    Oct 2008
    Posts
    115
    If you take out the curly braces from the script you wrote, it should fail because of a line starting with a pipe character... So I don't understand what kind of change you made when you say you removed the curly braces.

    There's something wrong with the output you provide for "cat./giga.aks.out" - it should never include "A.B" or "====="...

    Also note that since you're using the -a argument to "tee", previous runs' data will still be in the output file, so even if a particular run didn't add anything to the log file, there will still be something there...

Posting Permissions

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