--- Sub-shell / Current shell ---

(*1)
    echo -e "aaa\nbbb\nccc\nddd" > tmp
    value=0;
    while read line; do
        value=$(expr $value + 1)
        echo $value
    done < tmp
    rm -f tmp
    echo "at last: $value"

    result:
    1
    2
    3
    4
    at last: 4

(*2)
    value=0
    echo -e "aaa\nbbb\nccc\nddd" | while read line; do
        value=$(expr $value + 1)
        echo $value
    done
    echo "at last: $value"

    result:
    1
    2
    3
    4
    at last: 0

It is interesting, isn't it? The main reason is, (*1) is executed in current shell. But (*2) is executed in sub-shell. In more detail, there is only one process(current shell) during run at (*1). But at (*2), there are three processes; current shell, process for 'echo' and process for 'while loop'.

--- Shell function ---

(*1)
    function func_name() {
        ...
    }

(*2)
    func_name() {
        ...
    }

(*2) is more portable than (*1). Bash supports both (*1) and (*2). But, dash - /bin/sh -> dash in Ubuntu - doesn't support (*1).

--- Syntax ---
'()' grouping and '{}' grouping is delicately different in it's syntax.

(echo 1; echo 2; exit 0) # OK
{ echo a; echo b; exit 1 } # syntax error
{ echo a; echo b; exit 1; } # OK

 
--- Test ---
'!' has higher priority than '-a' and '-o'.

Assume that there are two files; 'a' and 'b'

[ -r a -a -r b ] : TRUE
[ ( -r a -a -r b ) ] : syntax error
[ ( -r a ) -a ( -r b ) ] : syntax error
[ ! -r a -o -r c ] : FALSE
[ ! -r a -o -r b ] : TRUE

 
--- Replacement ---
'~' isn't replaced in "". So,

MYHOME=~ # OK
MYHOME="~" # it doesn't work as expected

 
--- Symbolic link ---
Assume following file structure.

/data/userA/
/data/userB/
/home/a (a -> /data/userA/)
/home/b (b -> /data/userB/)

Let's see the following test.

cd /home/
cd a
pwd
    -> '/home/a' is shown.
ls ..
    -> 'userA' and 'userB' are shown. -- (*a)
cd ..
pwd
    -> '/home' is shown -- (*b)
ls
    -> 'a' and 'b' are shown. -- (*c)
cd /home/
cd a
cp a.txt ../
    -> a.txt is created at '/data/' -- (*d)

As you can see, the way handling symbolic link is different among commands. In above test, 'cd' and 'pwd' work differently from 'ls' and 'cp'. Some commands - like 'cd' and 'pwd' - handle directory path of working directory but some - like 'cp' and 'ls' - doesn't.
Therefore, try to use 'absolute path' to avoid the case like this, if symbolic link is included in the directory path.

+ Recent posts