Shell Learning

echo
echo '<context>' : no need to worry about the special character
echo "<context>": need to worry about the special character. need add "\" before it
But for variable you have to use " not '
Example:
echo 'test $ test' --> test $ test
echo "test $ test" --> test
echo "test \$ test" --> test $ test

#!/bin/bash
fruit=apple
count=5
echo "We have $count ${fruit}(s)"

Result: We have 5 apple(s)

echo "4 * 0.56"|bc --> 2.24
echo "scale=2;3/8"|bc --> .37
echo "scale=5;3/8"|bc --> .37500
echo "obase=2;ibase=10;100"|bc --> 110100
echo "obase=10;ibase=2;11100"|bc --> 28
echo "sqrt(100)"|bc --> 10
echo "10^2"|bc --> 100

stdin --> 0
stdout --> 1
stderr --> 2

stderr: change the error message output position
cmd 2><file name> : the error message print to file not terminal
Example: ls + 2>1.txt
cmd 2>/dev/null: no need to see the error message

stdout: change the output message output position
cmd 1><file name>: the result of the command print to file not terminal
Example: ls -l 1>1.txt
cmd > <file name> 2>&1: combine the stderr and stdout
Example: ls -l > 1.txt 2>&1

Array
#!\bin\bash
array_var=(1 2 3 4 5 6)
array_var[0]="test1"
array_var[1]="test2"
array_var[2]="test3"
array_var[3]="test4"
array_var[4]="test5"
array_var[5]="test6"

echo ${array_var[0]} --> test1
echo ${array_var[*]} --> test1 test2 test3 test4 test5 test6
echo ${array_var[@]} --> test1 test2 test3 test4 test5 test6
echo ${#array_var[*]} --> 6

Associate Array
#!\bin\bash
declare -A fruits_value
fruits_value=([apple]='100' [orange]='150')
echo "Apple costs ${fruits_value[apple]}" --> Apple costs 100
echo "Apple costs ${!fruits_value[*]}" --> apple orange
echo "Apple costs ${#fruits_value[*]}" --> 2

tput setb {0 - 7}: set terminal background color
tput setf {0 - 7}: set terminal font color
tput bold: set character bold
tput bold off: set character normal

Date display

Example:
date "+%d %B %y" -->25 June 15

Compile 
Outside shell program: #bash -x <script.sh>
Inside shell program:
set -x: show parameter and command
set +x: not show
set -v: print input
set +v: not prinit input

function

Example 1.sh
fname()
{
        echo $1, $2;
        echo "$@";
        echo "$*";
        return 0;
}

fname 34 56;

Result:
34, 56
34 56
34 56

Security: in order to prevent the number of process overload
change setting in /etc/security/limits.conf 

Check last command reture: echo $?
If it show 0, menas command run successfully.

Save the command output: cmd_output=`$(ls | cat -n)` --> it shows the ls result and add line number for it

sub-shell directory
sub-shell directory did not impact on the main one
example: 1.sh
pwd;
(cd /bin; ls);
pwd;

inform user to input parameter
read -p "Enter input:" var
abc
echo $var -->abc

let user input with ending as ":"
read -d ":" var
asdfasfdsaf:
echo $var --> asdfasfdsaf

Shell process single line file
1.txt: name,sex,rollno,location
1.sh:
data=`more 1.txt`

oldIFS=$IFS
IFS=,
for item in $data;
do
        echo item: $item
done
IFS=$oldIFS

Program Result
item: name
item: sex
item: rollno
item: location

Shell process single line file and specific item
1.txt:
root:x:0:0:root:/root:/bin/bash

1.sh:
data=`more 1.txt`

oldIFS=$IFS
IFS=:
count=0
for item in $data;
do
       [ $count -eq 0 ] && user=$item;
       [ $count -eq 0 ] && shell=$item;
       let count++
done
IFS=$oldIFS
echo $user\'s shell is $shell;

Program Result
root's shell is /bin/bash

Shell process multi lines file and specific item
1.txt:
cp /etc/passwd /tmp/1.txt

1.sh:
IFS="
"

for LINE in `cat /tmp/1.txt`
do
        IFS=:
                count=0
                for item in $LINE;
                do
                        [ $count -eq 0 ] && user=$item;
                        [ $count -eq 6 ] && shell=$item;
                        let count++
                done
                IFS="
                "
                echo $user\'s shell is $shell;
done

Program Result
root's shell is /bin/bash
...
apache's shell is /sbin/nologin

Additional
 [ $count -eq 0 ] && user=$item; 
 [ $count -eq 6 ] && user=$item; 

Change writing method

if [ $count -eq 0 ]; then
    user=$item;
elif [$count -eq 6]; then
    shell=$item;
fi

If confition for file, directory
1. [ -f $var ]: result true when file exist and is a regular file
2. [ -d $var ]: result true when directory exist
3. [ -e $var ]: result true when file exist
4. [ -r $var ]: result true when file exist and readable
5. [ -w $var ]: result true when file exist and writable
6. [ -x $var ]: result true when file exist and executable
7. [ -b $var ]: result true when block file exist
8. [ -L $var ]: result true when symbolic file exist

Example
/tmp/1: ln -s /tmp/1.sh /tmp/1

1.sh:
file=/tmp/1

if [ -L $file ]; then
        echo "file exist";
else
        echo "file not exist";
fi

Program result: file exist

If confition for string
[[ $str1==$str2 ]]: result true when str1 same as str2
[[ $str1!=$str2 ]]: result true when str1 different with str2
[[ $str1>$str2 ]]: result true when str1 bigger than str2
[[ $str1<$str2 ]]: result true when str2 bigger than str1
[[ -z $str ]]: result true when str is null
[[ -n $str ]]: result true when str is not null

cat command
1. cat used to get rid of blank line: cat <file>|tr -s '\n'
2. cat show tab as ^l
Example: 
1.sh
#!/bin/bash

file=/tmp/1

if [ -L $file ]; then
        echo "file exist";
else
        echo "file not exist";
fi

cat -T 1.sh
#!/bin/bash

file=/tmp/1

if [ -L $file ]; then
^Iecho "file exist";
else
^Iecho "file not exist";
fi

3. cat show line number
Example: 
1.sh
#!/bin/bash

file=/tmp/1

if [ -L $file ]; then
        echo "file exist";
else
        echo "file not exist";
fi

cat -n 1.txt
     1  #!/bin/bash
     2
     3  file=/tmp/1
     4
     5  if [ -L $file ]; then
     6          echo "file exist";
     7  else
     8          echo "file not exist";
     9  fi

Record script and replay
1. Record: 
script -t 2>timing.log -a output.session
type commands
...
...
exit
2. Replay:
scrptreplay timing.log output.session

Find parameter
find /tmp -name "1*" --> file start with 1
find /tmp ! -name "1*" --> file not start with 1

find parameters:
-maxdepth: max depth of directory
-mindepth: min depth of directory

-type: file type (f: file, l: link, d: directory, c: character, b: block, s: scoket, p: fifo)
-name: file name

-atime: last visit time of file (-7: wthin 7 days; 7: exact 7 days ago; +7: outside 7 days)
-mtime: last context modify time of file (-7: wthin 7 days; 7: exact 7 days ago; +7: outside 7 days)
-ctime: last privilege modify time of file (-7: wthin 7 days; 7: exact 7 days ago; +7: outside 7 days)

-amin: last visit time of file (-7: wthin 7 mins; 7: exact 7 mins ago; +7: outside 7 mins)
-mmin: last context modify time of file (-7: wthin 7 mins; 7: exact 7 mins ago; +7: outside 7 mins)
-cmin: last privilege modify time of file (-7: wthin 7 mins; 7: exact 7 mins ago; +7: outside 7 mins)

-size: file size (-2k: smaller than 2KB; 2k: exact 2KB; +2k: bigger than 2KB)
b: block (512Byte) 
c: Byte
w: 2 Byte
k: KB
M: MB
G: GB

-delete: find file and delete 
-perm: file privilege (find . -perm 644)
-user: file owner
-exec: combin find with further operation 
Example: 
find . -type f -user root -exec ls -l {} \;
find . -type f -user root -exec cp {} /tmp \;

find get rid of specific folder or file: find . \( -name "1.sh" -prune \) -o \( -type f -print \)

xargs command
1. Convert multi line txt to single line
1.txt
1 2 3 4 5 
6 7 8 
9 10

cat 1.txt|xargs --> 1 2 3 4 5 6 7 8 9 10

2. Convert multi line and every line contain different number of item to exacl number of item of each line
1.txt
1 2 3 4 5 
6 7 8 
9 10

cat 1.txt|xargs -n 5 --> 
1 2 3 4 5 
6 7 8 9 10

cat 1.txt|xargs -n 4 --> 
1 2 3 4 
5 6 7 8
9 10
 
3. Default separate item is " ", custom define separate item -d <character>
echo "name:sex:dob"|xargs -d : --> name sex dob

Comments

Popular posts from this blog

Nginx Proxy & Load Balance & LNMP

Snort+barnyard2+Snorby CentOS 6.5_64 Installation

ORACLE Error