LInux Shell 脚本笔记

时间:2014-07-22 23:00:55   收藏:0   阅读:382

*************************** list.txt : 目录 ********************************

1. variable.sh
2. condition.sh
3. control.sh
4. AndOr.sh
5. statementBlock.sh
6. function.sh
7. command_1.sh
8. old_version_set.sh
9. new_version_set.sh
10. command_2.sh
11. command_3.sh
12 another.sh
13. command_4.sh
14. command_5.sh
15. command_6.sh
16. command_7.sh
17. command_8.sh
18. dialog.sh

 

************** 1 . variable.sh : start ************
#!/bin/sh

#
# Shell变量,环境变量
# 运行时带几个参数: ./variable.sh you me her him them it

echo ---------普通变量------------
myvar="Hi there!"   
echo $myvar         #打印变量值
echo "$myvar"       #双引号可避免空格问题,但不抑制变量解析
echo ‘$myvar‘       #单引号抑制变量解析
echo \$myvar        #‘$‘被‘\‘转义

echo Please enter some text:
read myvar          #键盘输入
echo ‘$myvar‘ now equals : $myvar

echo ---------环境变量------------
echo [$IFS]         #Input Field Separator

echo ‘$0:‘ $0        #shell程序文件名
echo ‘$$:‘ $$        #进程ID
echo ‘$?:‘ $?        #最后运行的命令的结束代码(返回值)

echo ‘$*:‘$*        #所有参数
echo ‘$@:‘$@        #所有参数,但不使用$IFS
echo ‘$#:‘$#        #参数个数
echo args: $1,$2,$3,$4,$5   #第1到第5个参数

set -o verbose      #在命令执行前在屏幕上回显命令
echo ‘$-:‘$-        #使用Set命令设定的Flag一览

exit 0
************** 1 . variable.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 2 . condition.sh : start ************
#!/bin/bash

#
# Shell脚本条件测试:用test或[都可  (‘[‘也是一个命令,位于/usr/bin/)
#

#字符串比较
if [ "you" = "me" ]     #‘!=‘表字符串判不等
then
    echo "you = me"
else
    echo "you != me"
fi

if [ -z "" ]            #‘-n‘表不为空
then
    echo "string is NULL"
else
    echo "string is not NULL"
fi

#算术比较
if test 3 -eq 4         #-ne (这里的3,4可以是更复杂的表达式)
then
    echo "3 = 4"
else
    echo "3 != 4"
fi

if [ 5 -gt 6 ]          #-ge, -lt, -le, !
then
    echo "5 > 6"
else
    echo "5 <= 6"
fi

#文件条件测试
#文件存在:通常用‘-f‘代替,因为‘-e‘可能不可移植
if test -e fred.c; then     #then也可以放在这,但要‘;‘分隔
    echo "fred.c is exist"
else
    echo "no file fred.c"
fi

#是普通文件
if [ -f fred.c ]            #‘[‘与测试内容之间必须有空格,因为‘[‘是个命令名
then
    echo "fred.c is a general file"
else
    echo "fred.c is not a general file"
fi

# -d 是一个目录
# -r,-w,-x 文件可读,写,执行
# -u,-g 文件的SUID,SGID被设置
# -s 文件的长度不为0
exit 0
************** 2 . condition.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 3 . control.sh : start ************
#!/bin/bash

#
# Shell的控制语句
#

#if
echo "Is it morning? Please answer yes or no:"
read timeofday

if [ "$timeofday" = "yes" ]  #若$timeofday不加双引号,且为空(未输入,直接按回车)的话,会产生语法错误:if [ = "yes" ]
then
    echo "Good morning!"
elif [ "$timeofday" = "no" ]
then
    echo "Good afternoon!"
else
    echo "Sorry, it‘s not recognized: \"$timeofday\""
    exit 1
fi

#for
for var in bar fud 45 "hehe you sob"      #Shell认为所有变量包含的都是字符串,如这里的45
do
    echo $var
done

for file in $(ls *.sh); do      #$(cmd)
    echo $file
done

#while
foo=1
while [ "$foo" -le 20 ]
do
    echo -n "foo = $foo,"        #-n是bash的echo带的去换行参数,不是所有shell都有
    foo=$(($foo+1))         #$(())结构为算数扩展,替换会里面的表达式的值
done

#until
#若是该shell脚本的第一个参数指定的用户登录,则发警报
until who | grep "$1" > /dev/null   #who列出已登陆的用户
do
    sleep 5
done

echo -e \\a         #响铃(我机器上没有声音?)
echo "**** $1 has just logged in ! ****"

#case: case结构会使用第一个匹配的模式,即使后面的模式更精确
echo "is it morning ? Please answer yes or no:"
read timeofday

case "$timeofday" in
    [Yy][Ee][Ss] | [Yy])    echo "Good morning";;       #每个模式之后以";;"结尾,可放置多条语句
    no | n)    
        echo "you say no or n"
        echo "Good afternoon";;
    *)  echo "Soory, answer not recognized"  #*通配符匹配所有
        echo "please answer yes or no"
        exit 1
        ;;      #esac前的;;可省略
esac

exit 0
************** 3 . control.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 4 . AndOr.sh : start ************
#!/bin/bash

touch file_one
rm -f file_two

#AND列表:&&
#[ -f file_two ]测试失败,echo " two"不会执行
if [ -f file_one ] && echo "one" && [ -f file_two ] && echo " two"
then
    echo "true"
else
    echo "false"
fi


#OR列表:||
rm -f file_one

if [ -f file_one ] || echo "one" || echo "One"
then
    echo "true"
else
    echo "false"
fi


#混用AND和OR列表: 这里没有用if
#如果测试为真执行命令1, 为假执行命令2
[ -f file_one ] && echo "test for true: cmd1" || echo "test for false: cmd2"

exit 0
************** 4 . AndOr.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 5 . statementBlock.sh : start ************
#!/bin/bash

#语句块: {}
if {
    echo "We in block"
    echo "You in block"
    echo "They in block"
}
then {
    echo "true"
    echo "I said true"
}
else
    echo "false"
fi
************** 5 . statementBlock.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 6 . function.sh : start ************
#!/bin/bash

#
#Shell函数
#

func() {
    echo "this"
    echo "that"
    ls /bin/ls
    echo "result"

    return 0
}

#直接调用函数
func

echo "-----------------------------"

#res会捕获func()函数echo的字符串
res="$(func)"   #调用函数就跟使用其他命令一样

echo "func() executed completely:"
echo $res

echo "-----------------------------"

#函数内局部变量
func2() {
    local res="local res"               #local声明局部变量
    echo "Inside func2(): res=$res"
}

func2
echo "Outside func2(): res=$res"

echo "-----------------------------"

#从函数返回一个值
yes_or_no() {
    echo "Is your name $* ?"        #这里的$*是传给函数的所有参数,不是传给shell程序的参数
    while true
    do
        echo -n "Enter yes or no: "
        read x
        
        case "$x" in
            y | yes)    return 0;;
            n | no)     return 1;;
            *)          echo "Answer yes or no please."
        esac
    done
}

if yes_or_no "$1"   #调用函数并传递参数,根据return值判断执行成功还是失败
then
    echo "Hi, $1"   #仅当return 0时执行这句
else
    echo "Who you are"
fi

exit 0
************** 6 . function.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 7 . command_1.sh : start ************
#!/bin/bash

#
# Shell命令
#

#命令1:"break"
echo ----------------break----------------
rm -rf fred*
echo > fred1    #new file
echo > fred2
mkdir fred3     #new directory
echo > fred4

for file in fred*
do
    if [ -d "$file" ]; then
        break;                  #是目录则跳出
    fi
done

echo I got a directory: $file

rm -rf fred*

#命令2:"continue"
echo ---------------continue--------------
rm -rf fred*
echo > fred1    #new file
echo > fred2
mkdir fred3     #new directory
echo > fred4

for file in fred*
do
    if [ -d "$file" ]; then
        continue;                  #是目录则马上进入下一次循环
    fi
    echo I got a file: $file
done

rm -rf fred*

echo ---------------:-------------------
#命令3:":"        //一个空命令,相当于true
if [ -f fred ]; then
    :
else
    echo "file fred did not exist"
fi


echo -------------.---------------------
#命令4:"."      //在当前shell中执行命令,而不是在子shell中执行(正如source命令,会改变当前环境)
echo 请在shell下用". ./old_version_set.sh",". ./new_version_set.sh"来查看效果




exit 0
************** 7 . command_1.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 8 . old_version_set.sh : start ************
#!/bin/bash

version=Old_version
PS1="Old> "
PATH=/bin:/usr/bin:/usr/local/Old_bin:.
************** 8 . old_version_set.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 9 . new_version_set.sh : start ************
#!/bin/bash

version=New_version
PS1="New> "
PATH=/bin:/usr/bin:/usr/local/New_bin:.
************** 9 . new_version_set.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 10 . command_2.sh : start ************
#!/bin/bash

#
#   shell命令
#

echo ------------echo----------------
#命令5:"echo"
#不换行显示
echo -n "string to output."     #-n代表不输出换行
echo -e "string to output.\c"   #开启转义,\c代表结束输出(请看:man echo)


echo    #换行
echo ------------eval--------------
#命令6:"eval"           //对参数求值:像另一个$,它给出一个变量的值的值
foo=10
x=foo
y=‘$‘$x         #y=‘$foo‘
echo $y

eval y=‘$‘$x    #y=$foo=10
echo $y


echo ------------exec-------------
#命令7:"exec"   //exec命令在执行时会把当前的shell进程关闭,然后换到后面的命令继续执行。
#如:"exec touch afile"      //会关闭shell,并创建文件afile.


echo -------------exit-------------
#命令8:"exit"
exit 0  #成功
exit 1  # 1-125表错误码
#126表文件不可执行,127表命令未找到,128及以上表出现一个信号
************** 10 . command_2.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 11 . command_3.sh : start ************
#!/bin/bash

#
# shell命令
#

echo -------------export--------------
#命令9:"export"
foo="The first var"
export bar="The second var" #被导出
foo12="The 1.5th var"

#或set -allexport,表示导出后面声明的所有变量
set -a  
foo2="The third var"    #被导出
bar2="The fourth var"   #被导出

./another.sh        #调用另一个shell脚本,它只能看见导出的bar变量,而看不到foo

echo -----------expr------------
#命令10:"expr"      //将它的参数作为一个表达式来求值
x=3
echo "$x"
x=`expr $x + 1`     #可替换为$((...))语法,更有效
echo "$x"
x=$(expr $x + 1)
echo "$x"

echo -------------printf------------
#命令11:"printf"        //较新的版本shell提供该命令产生格式化输出,用来代替echo
y="you are not you."
printf "%s:x=%d,y=\"%s\"\n" "info" "$x" "$y"    #$y要用""包围

echo -----------set--------------
#命令12:"set"           //为shell设置参数变量,就像脚本的参数(命令9用法不太一样)
set $(date)     #设置参数为date命令的输出(空格分隔的)
echo $0,$1,$2,$3
set 1 "go you" 5000
echo $1,$2,$3

echo -----------shift-----------
#命令12:"shift"         //将所有的参数变量左移一个位置:$2变为$1...,注意$0不变
while [ "$1" != "" ]; do
    echo "$1"
    shift
done

exit 0
************** 11 . command_3.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 12 . another.sh : start ************
#!/bin/bash

echo "$foo"
echo "$bar"

echo "$foo12"

echo "$foo2"
echo "$bar2"
************** 12 . another.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 13 . command_4.sh : start ************
#!/bin/bash

#
# shell命令
#

echo --------------unset---------------
#命令14:"unset"     //从环境中删除变量或函数,但不能删除shell本身定义的只读变量如PATH
foo="Oh I‘am here"
echo $foo

foo=        #将foo设为空,变量仍存在
echo $foo

foo="Oh i am here again"
echo $foo
unset foo   #将foo变量删除掉
echo $foo


echo --------------trap------------------
#命令15:"trap"          
#   trap cmd signal: 当信号signal出现时,执行命令cmd(该命令之后有效)
#   trap signal: 忽略信号signal
#   trap - signal: 恢复signal的默认处理
trap ‘rm -f /tmp/my_tmp_file_$$‘ INT    #可以用trap -l看到INT信号
echo createing file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$

echo "press CTRL+C to interrupt ..."
while [ -f /tmp/my_tmp_file_$$ ]; do
    echo File exists
    sleep 1
done
echo "File no longer exists"

#设置回CTRL+C信号的默认处理:终止程序
trap INT
echo createing file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$

echo "press CTRL+C to interrupt ..."
while [ -f /tmp/my_tmp_file_$$ ]; do
    echo File exists
    sleep 1
done
echo "should not reach here"
************** 13 . command_4.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 14 . command_5.sh : start ************
#!/bin/bash

#
# shell
#

echo -----------find------------
#命令16:"find"
#find [path] [options] [test] [actions]
find . -name fun*.sh -print
echo -------

find / -mount -name wish    #-mount不去搜索挂载的其他文件系统
echo -------

find . -newer command_2.sh -type f     #搜索比command_2.sh要新的文件,不是目录
echo -------

find . -newer command_2.sh -o -name "v*.sh"   #-o表示或者,-a表示并且,!表非
echo -------

find . -newer command_2.sh -or -name "v*.sh"   #-or表示或者,-and表示并且,-not表非
echo -------

#用圆括号来组合测试(不用也是成功的)
find . \( -newer command_2.sh -o -name "v*.sh" \) -type f -print
echo -------

#找到匹配的文件后,可以执行指定的动作:
find . -name "c*" -exec ls -l {} \;     #-exec或-ok命令将后续参数作为他们的参数直到被"\;"终止,魔串"{}"会被当前文件的完整路径取代
************** 14 . command_5.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 15 . command_6.sh : start ************
#!/bin/bash

#
# shell命令
#

echo ----grep: General Regular Expression Parser----
#grep [option] pattern [files]
grep "if" ./condition.sh

echo ----------
grep -c "if" ./condition.sh ./command_1.sh  #搜索多个文件,只输出匹配行数

echo ----------
grep -v "i" ./condition.sh      #匹配不出现"i"的行

echo ---------
grep ^# ./condition.sh      #行首为用‘^‘,行尾用‘$‘

echo -----------
grep [[:blank:]]echo[[:blank:]] ./condition.sh      #[]中可以使用特殊匹配模式,[:blank:]表示空格或制表符

echo ------------
grep -E [a-z]\{5\} ./condition.sh   #-E开启扩展匹配:? * + {n} {n,} {n,m}  //匹配0或1次,0或多次,1或多次,n次,n次及以上,n到m次

************** 15 . command_6.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 16 . command_7.sh : start ************
#!/bin/bash

#
# shell命令的执行
#

# $(cmd)的结果就是cmd命令的输出     //只有需要脚本可移植时才应该用`cmd`(当命令中有特殊字符时要转义)
echo ‘------------$(cmd)-------------‘
echo Current user: $(who)
whoisthere=`who`
echo Current user: $whoisthere

echo --------------${var}------------
# 参数扩展: ${var}      //如${i}_tmp会扩展变量i,而$i_tmp会扩展变量i_tmp
for i in 1 3 5
do
    echo cmd_${i}_cmd
    echo CMD_$i_CMD     #$i_CMD会被扩展为空,不会报错!
done

echo --------
# ${param:-default}     若param为空,则把扩展为default
# ${#param}             扩展为param的长度
# ${param%word}         在param的尾部删除与word匹配的最短串,返回剩余部分
# ${param%%word}        尾部,删最长匹配
# ${param#word}         头部,删最短匹配
# ${param##word}        头部,删最长匹配
unset foo
echo ${foo:-hello you}  #foo为空,扩展为hello you

foo=something
echo ${foo:-Hello}      #foo不为空,扩展为something

foo=/usr/bin/X11/startx
echo ${foo#*/}          #删去头部/
echo ${foo##*/}         #删去头部/usr/bin/x11/

bar=/usr/local/etc/local/networks
echo ${bar%local*}      #删去尾部local/networks
echo ${bar%%local*}     #删去尾部local/etc/local/networks

echo ‘-----example for ${ }------‘
touch 1.gif 2.gif 3.gif
ls *.gif *.jpg

for image in *.gif
do
    mv $image ${image%%gif}jpg      #效果如: mv 1.gif 1.jpg
done
ls *.gif *.jpg
rm *.jpg

#另外:
# ${param:+default}     若param不为空,则返回default
# ${param:=default}     若param为空,则赋值为default,再返回;否则直接返回param的值
# ${param:?default}     若param为空,则输出param: default;否则返回param


************** 16 . command_7.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 17 . command_8.sh : start ************
#!/bin/bash

# <<TAG 和 TAG中间的内容就好象是标准输入的内容
echo ‘--------------<<TAG--------------‘
cat <<!SomeText!
hello you little boy.
hello you boy.
hello you.
hello.
!SomeText!

echo -------------
echo "hello." > hei.txt
echo "hello you." >> hei.txt
echo "hello you boy." >> hei.txt
echo "hello you little boy." >> hei.txt
cat ./hei.txt

echo -------------
#用ed编辑文件hei.txt,编辑命令为1,d,2,...
#  下面的‘$‘用‘\‘转义,为了防止shell对其做解释,因为要解释它的应该是ed
ed ./hei.txt <<!SomeOperations!
1
d
2
\$s/you/me/
w
q
!SomeOperations!
cat ./hei.txt
rm ./hei.txt

#调试shell程序
# set -o noexec, 简写set -n, 命令行sh -n foo.sh         //只检查语法,不执行
# set -o verbose, 简写set -v, 命令行sh -v foo.sh        //执行命令前先回显
# set -o xtrace, 简写set -x, 命令行sh -x foo.sh         //执行命令后回显
# set -o nounset, 简写set -u                            //若使用了未定义的变量,给出出错信息
echo ‘----------set -v---------‘
set -v
ls
set +v          #+v表示关闭verbose选项

echo ‘----------set -u---------‘
set -u
#echo $nodefine  #使用了为定义的变量,给出错误信息

#捕获退出信号,输出变量值
echo ------------trap handler signal-----------
foovar="i‘m something important."
trap ‘echo Exiting: foovar= $foovar‘ EXIT

************** 17 . command_8.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 
                                              
************** 18 . dialog.sh : start ************
#!/bin/bash

#dialog命令: linux控制台下的简单GUI程序
#对话框   标题                  消息框
dialog --title "Message you" --msgbox "Tell you something you do not know." 8 40
if [ $? = 0 ]; then
    dialog --infobox "your choose: OK" 5 20
    sleep 1
    dialog --clear
fi

#对话框   标题                       复选列表    提示        高  宽 选项数 选项编号,文本,状态....                      标准错误重定向(dialog的输出)
dialog --title "Check box example" --checklist "Pick Number" 15  25   3     1 "one" "off" 2 "two" "on" 3 "three" "off"  2> /tmp/tmp_file_$$.txt
ret=$?                                  #保存dialog的返回值
res=$(cat /tmp/tmp_file_$$.txt)         #保存dialog的输出值(用户选择的选项)
if [ $ret = 0 ]; then
    dialog --infobox "Your choise: $res" 10 30
else
    dialog --infobox "Bad, you canceled!" 10 30
fi

echo "$res"
#

************** 18 . dialog.sh : end **************
                                              
                @ @                         
                 ( V )                        
                  ^ ^                         
                       .=.=.0                 

************** 19. merge.sh : 合并list.txt中列出的当前目录下的文件 **************************

#!/bin/bash

if [ -f list2.txt ]
then
    rm -f list2.txt
fi

cat ./list.txt | while read line      #读取list.txt的每一行
do
    echo ${line#*[[:blank:]]} >> list2.txt      #去掉行首的序号和空白字符
done


x=0         #文件序号
if [ -f merged.txt ]
then
    rm -r merged.txt
fi

cat ./list2.txt | while read line
do
    x=$(($x + 1))
    echo "************** $x . $line : start ************" >> merged.txt
    cat ./$line >> merged.txt
    echo "************** $x . $line : end **************" >> merged.txt
    echo "                                              " >> merged.txt
    echo "                  @ @                         " >> merged.txt
    echo "                 ( V )                        " >> merged.txt
    echo "                  ^ ^                         " >> merged.txt
    echo "                       .=.=.0                 " >> merged.txt
    echo "                                              " >> merged.txt
done

if [ -f list2.txt ]
then
    rm -f list2.txt
fi                                       

***********************************  End ***********************************      

LInux Shell 脚本笔记,码迷,mamicode.com

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!