shell编程基础

shell学习笔记

##变量
 
##普通变量:
  eg1:
  name=axe
  echo $name
  ps.等号两遍不能有空格,否则会报错.
  eg2:
  name="axe prpr"
  echo $name
  or
  name='axe prpr'
  echo $name
  ps.双引号中可以引用其他变量,单引号不可以。
  eg:
  name=axe
  fullname="$name prpr"
  echo $fullname
  eg3:
  version=`uname -a`(在变量中引用命令)
  echo $version
  eg4:
  变量的扩增:
  echo $PATH
  PATH=${PATH}:/home/axe
  echo $PATH
  or
  PATH="$PATH":/home/axe

 如果希望预定义一个变量,但是暂时不给他赋值,可以使用decalre命令:

 declare INT_NUMBER

 typeset -i INT_NUMBER #使用typeset  -i 设置正式变量
 
##环境变量:
  env查看:
  `axe@axe:~$ env
   LC_PAPER=zh_CN.UTF-8
   LC_ADDRESS=zh_CN.UTF-8
   XDG_SESSION_ID=6
   LC_MONETARY=zh_CN.UTF-8
   TERM=vt100
   ……`
  or export查看.
  eg:
  name=axe
  echo $name
  bash(新建一个子程序)
  echo $name(此时没有输出)
  exit
  export name
  bash
  echo $name

##取消变量
  eg:
  name=axe
  echo $name
  unset name(取消变量)
  echo $name

##只读变量
  eg:
  name=axe
  readonly name
  name=prpr(此时报错)

##变量的展开替换
  eg:name=

  echo ${name}

  echo ${name:-noset} 如果name存在且不为null则返回其值,否则返回noset

  echo ${name:=noset} 如果name存在且不为null则返回其值,否则设置为noset

  echo ${name:?message} 如果name存在且不为null则返回其值,否则显示name:message

  echo ${name:+set } 如果name存在且不为null返回set,否则返回null

  ${variable#key} 从头开始删除关键字,最短匹配

  ${variable##key} 从头开始删除关键字,执行最长匹配

  ${varibale%key} 从尾开始删除关键字,执行最短匹配

  ${variable%%key} 从尾开始删除关键字,执行最短匹配

##特殊变量
  eg.eg:
  vi test2.sh
  `#!/bin/sh
   echo $$  #表示当前shell进程的ID
   echo $0  #表示当前的文件名
   echo $1  #表示脚本或函数的输入值
   echo $#  #表示传递给脚本或函数的参数个数
   echo $*  #表示传递给脚本或函数的所有参数
   echo $@  #表示传递给脚本或函数的所有参数
   echo $?  #表示函数的返回值
   #区别下$*和$@
   for i in $*
   do
       echo $i
   done
   for i in $@
   do
       echo $i
   done
   for i in "$*"
   do
       echo $i
   done
   for i in "$@"
   do
       echo $i
   done
   #不加""时,两个输出一样为"$1","$2"..加""时,$*会以"$1,$2.."输出
   #可以看出没什么吊用
  `
  wq!
  chmod +x test2.sh
  ./test2.sh a b
  执行结果为:
  `axe@axe:~/test$ ./test2.sh a b
   12304
   ./test2.sh
   a
   2
   a b
   a b
   0
   a
   b
   a
   b
   a b
   a
   b
   ps.这里的$?执行结果为0,表示当前shell上一个命令的退出状态为success.

##算术运算

  shell中算术运算使用$(())实现,eg:$((1+2))

  支持自增$((x++));mod$((x%y));幂运算$((x**y)) #x的y次方

  写一个斐波那契数列的shell:

  #!/bin/sh
  i=1;j=2
  function fibonacci(){
  echo $i
  echo $j
  i=$(($i+$j))
  j=$(($j+$i))
  fibonacci
  }
  fibonacci

 顺便斐波那契数列的自增比想象中快很多啊。

  算术运算也可以用expr实现:
  eg:
  vi test3.sh
  `#!/bin/sh
   value1=`expr 2 + 2`
   value2=`expr 2 - 2`
   value3=`expr 2 \* 2`
   value4=`expr 2 / 2`
   echo $value1
   echo $value2
   echo $value3
   echo $value4
  `
  输出结果为:4 0 4 1

##关系运算
  vi test4.sh
  `#!/bin/sh
   if [ $1 -eq $2 ];then
   echo "$1=$2"
   fi
   if [ $1 -ne $2 ];then
   echo "$1!=$2"
   fi
   if [ $1 -gt $2 ];then
   echo "$1>$2"
   fi
   if [ $1 -lt $2 ];then
   echo "$1<$2"
   fi
   if [ $1 -ge $2 ];then
   echo "$1>=$2"
   fi
   if [ $1 -le $2 ];then
   echo "$1<=$2"
   fi
   `   
##布尔运算符
   eg:
   if [ 1 -eq 2 -o 1 -lt 2 ];then echo true;fi;
   if [ 1 -ge 1 -a 1 -le 1 ];then echo true;fi;
   if [ ! 1 -eq 2 ];then echo true;fi;

##字符串运算符
   eg:
   if [ a = a ];then echo true;fi;
   if [ a != b ];then echo true;fi;
   if [ -z ];then echo true;fi;
   if [ -n a ];then echo true;fi;
   if [ str ];then echo true;fi;

##文件测试运算符
  file="/home/axe/test/test1.sh"
  if [ -r $file ];then echo true;fi;
  if [ -w $file ];then echo ture;fi;
  if [ -x $file ];then echo ture;fi;
  if [ -s $file ];then echo ture;fi;(是否为空)
  if [ -e $file ];then echo ture;fi;(是否存在)
  其余:
  `
  -b file     检测文件是否是块设备文件,如果是,则返回 true。     
  -c file     检测文件是否是字符设备文件,如果是,则返回 true。     
  -d file     检测文件是否是目录,如果是,则返回 true。
  -f file     检测文件是否是普通文件(既不是目录,也不是设备文件)
  -g file     检测文件是否设置了 SGID 位,如果是,则返回 true。
  -k file     检测文件是否设置了粘着位(Sticky Bit),如果是,则返回true。
  -p file     检测文件是否是具名管道,如果是,则返回 true。     
  -u file     检测文件是否设置了 SUID 位,如果是,则返回 true。
  `
##字符串
  name="axe prpr"
  echo $name
  echo ${#name} #表示字符串长度
  echo `expr index "$name" a` #表示字符a在$name中的位置
  name2="axe prpr $name" #双引号拼接字符串
  echo ${name:1:4} 提取字符串

##数组
  array=(a b c)
  echo ${array[1]}
  echo ${array[*]} #或者@
  echo ${#array[*]} #获取长度

  补充:这里同样可以使用declare命令预定义。ps.declare是bash版本2后才有的。
 
##条件选择
  #if else elif fi
  eg:
  a=b
  if [ -n $a ];then echo true;elfi [ -z $a ];then echo ture;fi;
 
  #case in ;; esac
  eg:
  #!/bin/sh
  case $1 in
  axe) echo "$1 is a name"
  ;;
  0904) echo "$1 is a date"
  ;;
  esac
 
  #for in do done
  eg:
  for file in /home/axe/test/*.sh
  do
      echo $file
  done
 
  #while do done
  eg:
  while read file;do echo "get $file";echo "type CTRL+D to terminate";done;
 
  #until do done
  eg:
  a=100;until [ `expr $a - 1` -le 0 ] ;do a=`expr $a - 1`;echo $a;done;(输出100-1)
 
  #break,continue
  略
 
##函数
  eg:
  function name(){
  name=axe
  echo $name
  }
  name
 
  eg2:函数的返回值
  function add(){
  return `expr 1 + 2`
  }
  add
  echo $?
 
  删除函数使用unset.f
 
  eg3:传参
  function calputer(){
  case $2 in
  +) echo `expr $1 + $3`;;
  -) echo `expr $1 - $3`;;
  *) echo `expr $1 \* $3`;;
  /) echo `expr $1 / $3`;;
  esac
  }
  calputer 1 + 2
 
##重定向
  eg:
  echo `pwd` > pwd.sh
  ls -l < pwd.sh

  linux中有一个特殊的设备/dev/null,任何写入此设备的东西将会永远消失。对于大量无意义的输出,可以通过重定向导入/dev/null

  echo "pass" | passwd --stdin root > /dev/null

  标准输出与错误输出分离重定向:

  id axe >>user 2>>error
 
##文件包含
  略

##命令序列的使用技巧

& 开启一个子shell后台运行

&&和|| 前者表示前一个命令执行成功则执行后一个命令,后者则相反。

eg:cat /etc/passwd | awk -F ':' '{print $1}' && echo "success "|| echo "error"
##作业控制

1.开启一个子进程并进入后台 firefox &

2.jobs 查看

3.fg 回调 eg:fg1

## {}使用技巧

echo {a,b,c} 显示a,b,c

echo user{1,2,3} 显示user1,user2,user3

echo {0..10}显示 0,1,2,3,4,5,6,7,8,9,10

echo {0..10..2} 显示 0,2,4,6,8,10

echo a{2..-1} 显示a2,a1,a0,a-1

mkdir /tmp/{dir1,dir2,dir3}

ls -ld /tmp/dir{1,2,3}

 



 
 
   

 

posted @ 2015-09-18 05:08  axeprpr  阅读(207)  评论(0)    收藏  举报