首页 > 代码库 > linux bash shell学习笔记

linux bash shell学习笔记

Bash

开头#!/bin/bashecho语句屏蔽若使用则 \” \”即使文件没有执行权限,仍然可以通过bashhello.sh或者 sh hello.sh来执行文件。

标准输出写入>>文件中,标准错误输出默认为屏幕。标准错误输出为2>>。错误和输出都写入文件:1>>log 2>>err。两者都写入同一个文件:>&all_result> all_result 2>& 1

赋值:[root@host1 ~]#my=‘hello‘ ‘=‘左右两边都不能有空格;标准调用变量${}.BASH中的变量既然不需要定义,也就没有类型一说,一个变量即可以被定义为一个字符串,也可以被再定义为整数。如果对该变量进行整数运算,他就被解释为整数;如果对他进行字符串操作,他就被看作为一个字符串.

数值计算:+号两边不能有空格Let x=${x}+1Let “x=$x+1”先进行数值计算。

比较计算:

        数值比较:-eq, -ne -gt -lt, -ge-le

   字符串比较: =,!=-z空, -n不为空, <,>

结构语句

If语句

if [ $x -eq $y];then echo eq;else echo nq;fi

if [ $x = $y];then echo eq;else echo nq;fi

if空格[空格语句空格]then语句;else语句;fi

变量可以为字符比较,也可以为数值比较

For语句

[root@host1 ~]#for i in xu ch l;do echo $i;done

xu

ch

l

[root@host1 ~]#for i in "xu ch l";do echo $i;done

xu ch l

for头中变量不需要${}

 

While语句:要给i付初值。

x=20

[root@host1 ~]#while [[ $i -lt $x ]];do let i=$i+1;echo $i;done

[root@host1 ~]#i=1

[root@host1 ~]#while [[ $i -lt $x ]];do let i=$i+1;echo $i;done

文件对象操作

if [ -e log ]; then echo yes;fi

 

等待键盘输入

 echo"Hit a key, then hit return."

 readKeypress

echo $Keypress

函数

#!/bin/bash

 

 square() {

 let"res = $1 * $1"

 return $res

 }

 square $1

 result=$?

 echo$result

 exit0

保留变量

 

$IFS  这个变量中保存了用于分割输入参数的分割字符,默认识空格。

$HOME 这个变量中存储了当前用户的根目录路径。

$PATH 这个变量中存储了当前 Shell的默认路径字符串。

$PS1  表示第一个系统提示符。

$PS2  表示的二个系统提示符。

$PWD  表示当前工作路径。

$EDITOR表示系统的默认编辑器名称。

$BASH 表示当前 Shell的路径字符串。

$0, $1, $2, ...

表示系统传给脚本程序或脚本程序传给函数的第0个、第一个、第二个等参数。

$#   表示脚本程序的命令参数个数或函数的参数个数。

$$   表示该脚本程序的进程号,常用于生成文件名唯一的临时文件。

$?   表示脚本程序或函数的返回状态值,正常为 0,否则为非零的错误号。

$*   表示所有的脚本参数或函数参数。

$@   和 $* 涵义相似,但是比 $*更安全。

$!   表示最近一个在后台运行的进程的进程号。

Select语句

[root@host1 ~]# select i in my word; doecho my;exit;done

 [root@host1~]# vi select.sh

#!/bin/bash

 OPTIONS="Hello Quit"

 select opt in $OPTIONS; do

 if ["$opt" = "Quit" ]; then

 echodone

 exit

 elif[ "$opt" = "Hello" ]; then

 echoHello World

 else

 clear

 echobad option

 fi

 done

 exit0

 [root@host1 ~]# bash select.sh

1) Hello

2) Quit

#? 1

Hello World

#? 2

Done

Here document

su - oracle <<!

rman target /<<EOF

backup AS COMPRESSED BACKUPSET  database

exit;

EOF

 

sqlplus / as sysdba << EOF

desc user_tables;

exit;

EOF

 

Su – oracle << BO

结尾加不加BO都可以。

Crontab

1列分钟159

2列小时1230表示子夜)

 3列日131

4列月112

5列星期060表示星期天)

 6列要运行的命令

  1. 0,30 18-23 * * * 每天18 : 0023 : 00之间每隔30分钟

  2. 45 4 1,10.,22 * * 上面的例子表示每月11022日的4 : 45

  3. 10 1 * * 6,0 每周六、周日的1 : 10

  4. * */1 * * * 每小时

  5. * 23-7/1 * * * 晚上11点到早上7点之间,每隔一小时

  6. */1 * * * * echo `date`>> /root/time.log 每分钟。

Case语句

#!/bin/bash

 

 echo"Hit a key, then hit return."

 readKeypress

 

 case"$Keypress" in

 [a-z] ) echo "Lowercase letter";;

 [A-Z] ) echo "Uppercase letter";;

 [0-9] ) echo "Digit";;

 * )echo "Punctuation, whitespace, or other";;

 Esac

数组

赋值

(1) array=(var1 var2 var3 ... varN)

(2) array=([0]=var1 [1]=var2 [2]=var3 ...[n]=varN)

(3) array[0]=var1

   arrya[1]=var2

   ...

array[n]=varN

计算数组元素个数:

${#array[@]} 或者 ${#array[*]}

 

${arry[*]} ${arry[@]}表示全部元素。

 

数组遍历文件名字

遍历数组:

filename=(`ls`)

for var in ${filename[@]};do

echo $var

done

 

取首元素

$arry

2、将字符串里的字母逐个放入数组,并输出到“标准输出”

chars=‘abcdefghijklmnopqrstuvwxyz‘

for (( i=0; i<26; i++ )) ; do

   array[$i]=${chars:$i:1}

   echo ${array[$i]}

done

字符串

长度

        echo${#x}

expr length $x

查找子串

1. %exprindex  $x "b"

2. 2

3. %exprindex  $x "a"

4. 1

5. %exprindex  $x "b"

6. 2

7. %exprindex  $x "c"

8. 3

9. %exprindex  $x "d"

10.4

获得子串

#方法一

# expr <string> startpos length

%expr substr "$x" 1 3

abc

%expr substr "$x" 1 5

abcd

%expr substr "$x" 2 5

bcd

#方法二

# ${x:pos:lenght}

%echo ${x:1}

bcd

%echo ${x:2}

cd

%echo ${x:0}

abcd

%echo ${x:0:2}

ab

%pos=1

%len=2

%echo ${x:$pos:$len}

Bc

 

匹配比较

#打印匹配长度

%expr match $x "."

1

%expr match $x "abc"

3

%expr match $x "bc"

0

 

字符串的替换。

%x=abcdabcd

%echo ${x/a/b} #只替换一个

bbcdabcd

%echo ${x//a/b} #替换所有

Bbcdbbcd

时间操作

#!/bin/sh 

 

 

# Copyright (c) 2010 codingstandards. Allrights reserved. 

# file: datetime.sh 

# description: Bash中关于日期时间操作的常用自定义函数 

# license: LGPL 

# author: codingstandards 

# email: codingstandards@gmail.com 

# version: 1.0 

# date: 2010.02.27 

 

 

# usage: yesterday 

#昨天 

#比如今天是2010227日,那么结果就是2010-02-26 

yesterday() 

{ 

   date --date=‘1 day ago‘ +%Y-%m-%d 

} 

 

# usage: today 

#今天 

#比如今天是2010227日,那么结果就是2010-02-27 

today() 

{ 

   date +%Y-%m-%d 

} 

 

# usage: now 

#现在,包括日期和时间、纳秒 

#比如:2010-02-2711:29:52.991774000 

now() 

{ 

   date "+%Y-%m-%d %H:%M:%S.%N" 

} 

 

# usage: curtime 

#当前时间,包括日期和时间 

#比如:2010-02-2711:51:04 

curtime() 

{ 

   date ‘+%Y-%m-%d %H:%M:%S‘ 

   #也可写成:date ‘+%F %T‘ 

} 

 

# usage: last_month 

#取上个月的年月 

#比如:2010-01 

last_month() 

{ 

   date --date=‘1 month ago‘ ‘+%Y-%m‘ 

} 

 

# usage: last_month_packed 

#取上个月的年月 

#比如:201001 

last_month_packed() 

{ 

   date --date=‘1 month ago‘ ‘+%Y%m‘ 

} 

 

# usage: first_date_of_last_month 

#取上个月的第一天 

#比如本月是20102月,那么结果就是2010-01-01 

first_date_of_last_month() 

{ 

   date --date=‘1 month ago‘ ‘+%Y-%m-01‘ 

} 

 

# usage: last_date_of_last_month 

#取上个月的最后一天 

#比如当前是20102月,那么结果就是2010-01-31 

last_date_of_last_month() 

{ 

   date --date="$(date +%e) days ago" ‘+%Y-%m-%d‘ 

} 

 

# usage: day_of_week 

#今天的星期 

# day of week (0..6); 0 represents Sunday 

day_of_week() 

{ 

   date +%w 

} 

 

# usage: last_hour 

#上个小时 

#比如:2010-02-27-10 

#适合处理log4j生成的日志文件名 

last_hour() 

{ 

   date --date=‘1 hour ago‘ +%Y-%m-%d-%H 

} 

 

# usage: the_hour 

#当前的小时,为方便算术比较,结果不以0开头 

#比如:12 

the_hour() 

{ 

   #date +%H  # hour (00..23) 

   date +%k   # hour ( 0..23) 

} 

 

# usage: the_minute 

#当前的分钟,为方便算术比较,结果不以0开头 

#比如: 

the_minute() 

{ 

   MM=$(date +%M) # minute(00..59) 

   echo $[1$MM-100] 

} 

 

# usage: the_second 

#当前的秒数 

#比如: 

the_second() 

{ 

   SS=$(date +%S) # second (00..60);the 60 is necessary to accommodate a leap second 

   echo $[1$SS-100] 

} 

 

# usage: the_year 

#当前的年份 year(1970...) 

#比如:2010 

the_year() 

{ 

   date +%Y 

} 

 

# usage: the_month 

#当前的月份,为方便算术比较,结果不以0开头 

#比如:2 

the_month() 

{ 

   M=$(date +%m) # month (01..12) 

   echo $[1$M-100] 

} 

 

# usage: the_date 

#当前的日期,为方便算术比较,结果不以0开头 

#比如:27 

the_date() 

{ 

   date +%e   # day of month, blankpadded ( 1..31) 

} 

 

# usage: days_ago <n> 

#n天前的日期 

#比如:days_ago 0就是今天,days_ago1就是昨天,days_ago 2就是前天,days_ago -1就是明天 

#格式:2010-02-27 

days_ago() 

{ 

   date --date="$1 days ago" +%Y-%m-%d 

} 

 

# usage: chinese_date_and_week() 

#打印中文的日期和星期 

#比如:227星期六 

chinese_date_and_week() 

{ 

   WEEKDAYS=(星期日星期一星期二星期三星期四星期五星期六) 

   WEEKDAY=$(date +%w) 

   #DT="$(date +%Y%m%d) ${WEEKDAYS[$WEEKDAY]}"    

   MN=1$(date +%m) 

   MN=$[MN-100] 

   DN=1$(date +%d) 

   DN=$[DN-100] 

   DT="$MN$DN ${WEEKDAYS[$WEEKDAY]}" 

   echo "$DT" 

} 

 

# usage: rand_digit 

#随机数字,0-9 

rand_digit() 

{ 

   S="$(date +%N)" 

   echo "${S:5:1}" 

} 

 

# usage: seconds_of_date [<date>[<time>]] 

#获取指定日期的秒数(自1970年) 

#比如:seconds_of_date"2010-02-27"返回 1267200000 

seconds_of_date() 

{ 

   if [ "$1" ]; then 

       date -d "$1 $2" +%s 

   else 

       date +%s 

   fi 

} 

 

# usage: date_of_seconds<seconds> 

#根据秒数(自1970年)得到日期 

#比如:date_of_seconds1267200000返回 2010-02-27 

date_of_seconds() 

{ 

   date -d "1970-01-01 UTC $1 seconds" "+%Y-%m-%d" 

} 

 

# usage: datetime_of_seconds<seconds> 

#根据秒数(自1970年)得到日期时间 

#比如:datetime_of_seconds1267257201返回 2010-02-27 15:53:21 

datetime_of_seconds() 

{ 

   date -d "1970-01-01 UTC $1 seconds" "+%Y-%m-%d%H:%M:%S" 

} 

 

# usage: leap_year <yyyy> 

#判断是否闰年 

#如果yyyy是闰年,退出码为0;否则非0 

#典型示例如下: 

# if leap_year 2010; then 

#  echo "2010 is leap year"; 

# fi 

# if leap_year 2008; then 

#  echo "2008 is leap year"; 

# fi 

#摘自脚本:datetime_util.sh(2007.06.11) 

#注:这个脚本来自网络,略有修改(原脚本从标准输入获取年份,现改成通过参数指定) 

# Shell program to read any year and findwhether leap year or not 

#----------------------------------------------- 

# Copyright (c) 2005 nixCraft project<http://cyberciti.biz/fb/> 

# This script is licensed under GNU GPLversion 2.0 or above 

#------------------------------------------------------------------------- 

# This script is part of nixCraft shellscript collection (NSSC) 

# Visit http://bash.cyberciti.biz/ for moreinformation. 

#------------------------------------------------------------------------- 

leap_year() 

{ 

   #store year 

   yy=$1 

   isleap="false" 

 

   #echo -n "Enter year (yyyy) : " 

   #read yy 

 

   #find out if it is a leap year or not 

 

   if [ $((yy % 4)) -ne 0 ] ; then 

       : # not a leap year : means donothing and use old value of isleap 

   elif [ $((yy % 400)) -eq 0 ] ; then 

       # yes, it‘s a leap year 

       isleap="true" 

   elif [ $((yy % 100)) -eq 0 ] ; then 

       : # not a leap year do nothing and use old value of isleap 

   else 

       # it is a leap year 

       isleap="true" 

   fi 

   #echo $isleap 

   if [ "$isleap" == "true" ]; then 

       # echo "$yy is leapyear" 

       return 0 

   else 

       # echo "$yy is NOT leapyear" 

       return 1 

   fi 

} 

 

# usage: validity_of_date <yyyy><mm> <dd> 

#判断yyyy-mm-dd是否合法的日期 

#如果是,退出码为0;否则非0 

#典型示例如下: 

# if validity_of_date 2007 02 03; then 

#  echo "2007 02 03 is valid date" 

# fi 

# if validity_of_date 2007 02 28; then 

#  echo "2007 02 28 is valid date" 

# fi 

# if validity_of_date 2007 02 29; then 

#  echo "2007 02 29 is valid date" 

# fi 

# if validity_of_date 2007 03 00; then 

#  echo "2007 03 00 is valid date" 

# fi 

#摘自脚本:datetime_util.sh(2007.06.11) 

#注:这个脚本来自网络,略有修改(原脚本从标准输入获取年月日,现改成通过参数指定) 

# Shell program to find the validity of agiven date 

#----------------------------------------------- 

# Copyright (c) 2005 nixCraft project<http://cyberciti.biz/fb/> 

# This script is licensed under GNU GPLversion 2.0 or above 

# ------------------------------------------------------------------------- 

# This script is part of nixCraft shellscript collection (NSSC) 

# Visit http://bash.cyberciti.biz/ for moreinformation. 

#------------------------------------------------------------------------- 

validity_of_date() 

{ 

   #store day, month and year 

   yy=$1 

   mm=$2 

   dd=$3 

 

   #store number of days in a month 

   days=0 

 

   #get day, month and year 

   #echo -n "Enter day (dd) : " 

   #read dd 

 

   #echo -n "Enter month (mm) : " 

   #read mm 

 

   #echo -n "Enter year (yyyy) : " 

   #read yy 

 

   #if month is negative (<0) or greater than 12  

   #then it is invalid month 

   if [ $mm -le 0 -o $mm -gt 12 ]; then 

       #echo "$mm is invalid month." 

       return 1 

   fi 

 

   #Find out number of days in given month 

   case $mm in  

       1) days=31;; 

       01) days=31;; 

       2) days=28 ;; 

       02) days=28 ;; 

       3) days=31 ;; 

       03) days=31 ;; 

       4) days=30 ;; 

       04) days=30 ;; 

       5) days=31 ;; 

       05) days=31 ;; 

       6) days=30 ;; 

       06) days=30 ;; 

       7) days=31 ;; 

       07) days=31 ;; 

       8) days=31 ;; 

       08) days=31 ;; 

       9) days=30 ;; 

       09) days=30 ;; 

       10) days=31 ;; 

       11) days=30 ;; 

       12) days=31 ;; 

       *) days=-1;; 

   esac 

 

   #find out if it is a leap year or not 

 

   if [ $mm -eq 2 ]; then # if it is feb month then only check of leapyear 

       if [ $((yy % 4)) -ne 0 ] ; then 

           : # not a leap year : means donothing and use old value of days 

       elif [ $((yy % 400)) -eq 0 ] ; then 

           # yes, it‘s a leap year 

           days=29 

       elif [ $((yy % 100)) -eq 0 ] ; then 

           : # not a leap year do nothing and use old value of days 

       else 

           # it is a leap year 

           days=29 

       fi 

   fi 

 

   #echo $days 

 

   #if day is negative (<0) and if day is more than  

   #that months days then day is invaild 

   if [ $dd -le 0 -o $dd -gt $days ]; then 

       #echo "$dd day is invalid" 

       return 3 

   fi 

 

   #if no error that means date dd/mm/yyyy is valid one 

   #echo "$dd/$mm/$yy is a vaild date" 

   #echo "$yy-$mm-$dd is a valid date" 

   #echo "valid" 

   return 0 

} 

 

# usage: days_of_month <mm><yyyy> 

#获取yyyymm月的天数,注意参数顺序 

#比如:days_of_month 22007结果是28 

days_of_month() 

{ 

   #store day, month and year 

   mm=$1 

   yy=$2 

 

   #store number of days in a month 

   days=0 

 

   #get day, month and year 

   #echo -n "Enter day (dd) : " 

   #read dd 

 

   #echo -n "Enter month (mm) : " 

   #read mm 

 

   #echo -n "Enter year (yyyy) : " 

   #read yy 

 

   #if month is negative (<0) or greater than 12  

   #then it is invalid month 

   if [ $mm -le 0 -o $mm -gt 12 ]; then 

       #echo "$mm is invalid month." 

       echo -1 

       return 1 

   fi 

 

   #Find out number of days in given month 

   case $mm in  

       1) days=31;; 

       01) days=31;; 

       2) days=28 ;; 

       02) days=28 ;; 

       3) days=31 ;; 

       03) days=31 ;; 

       4) days=30 ;; 

       04) days=30 ;; 

       5) days=31 ;; 

       05) days=31 ;; 

       6) days=30 ;; 

       06) days=30 ;; 

       7) days=31 ;; 

       07) days=31 ;; 

       8) days=31 ;; 

       08) days=31 ;; 

       9) days=30 ;; 

       09) days=30 ;; 

       10) days=31 ;; 

       11) days=30 ;; 

       12) days=31 ;; 

       *) days=-1;; 

   esac 

 

   #find out if it is a leap year or not 

 

   if [ $mm -eq 2 ]; then # if it is feb month then only check of leapyear 

       if [ $((yy % 4)) -ne 0 ] ; then 

           : # not a leap year : means donothing and use old value of days 

       elif [ $((yy % 400)) -eq 0 ] ; then 

           # yes, it‘s a leap year 

           days=29 

       elif [ $((yy % 100)) -eq 0 ] ; then 

           : # not a leap year do nothing and use old value of days 

       else 

           # it is a leap year 

           days=29 

       fi 

   fi 

 

   echo $days 

} 

 

文件:test_datetime.sh

Bash代码 

#!/bin/sh 

 

# TODO:注意根据datetime.sh的实际位置更改 

. /opt/shtools/commons/datetime.sh 

 

echo "当前时间(date):$(date)" 

echo "昨天(yesterday):$(yesterday)" 

echo "今天(today):$(today)" 

echo "现在(now):$(now)" 

echo "现在(curtime):$(curtime)" 

echo "上月(last_month):$(last_month)" 

echo "上月(last_month_packed):$(last_month_packed)" 

echo "上月第一天(first_date_of_last_month):$(first_date_of_last_month)" 

echo "上月最后一天(last_date_of_last_month):$(last_date_of_last_month)" 

echo "今天星期几(day_of_week):$(day_of_week)" 

echo "上个小时(last_hour):$(last_hour)" 

echo "当前的小时(the_hour):$(the_hour)" 

echo "当前的分钟(the_minute):$(the_minute)" 

echo "当前的秒钟(the_second):$(the_second)" 

echo "当前的年份(the_year):$(the_year)" 

echo "当前的月份(the_month):$(the_month)" 

echo "当前的日期(the_date):$(the_date)" 

echo "前天(days_ago 2):$(days_ago2)" 

echo "明天(days_ago -1):$(days_ago-1)" 

echo "后天(days_ago -2):$(days_ago-2)" 

echo "十天前的日期(days_ago 10):$(days_ago10)" 

echo "中文的日期星期(chinese_date_and_week):$(chinese_date_and_week)" 

echo "随机数字(rand_digit):$(rand_digit)" 

echo "随机数字(rand_digit):$(rand_digit)" 

echo "1970年来的秒数(seconds_of_date):$(seconds_of_date)" 

echo "1970年来的秒数(seconds_of_date2010-02-27):$(seconds_of_date 2010-02-27)" 

echo "1970年来的秒数(seconds_of_date2010-02-27 15:53:21):$(seconds_of_date 2010-02-27 15:53:21)" 

echo "1970年来的秒数对应的日期(date_of_seconds1267200000):$(date_of_seconds 1267200000)" 

echo "1970年来的秒数对应的日期时间(datetime_of_seconds1267257201):$(datetime_of_seconds 1267257201)" 

 

if leap_year 2010; then 

   echo "2010年是闰年"; 

fi 

if leap_year 2008; then 

   echo "2008年是闰年"; 

fi 

if validity_of_date 2007 02 03; then 

   echo "2007 02 03日期合法" 

fi 

if validity_of_date 2007 02 28; then 

   echo "2007 02 28日期合法" 

fi 

if validity_of_date 2007 02 29; then 

   echo "2007 02 29日期合法" 

fi 

if validity_of_date 2007 03 00; then 

   echo "2007 03 00日期合法" 

fi 

 

echo "20102月的天数(days_of_month2 2010):$(days_of_month 2 2010)" 

echo "20082月的天数(days_of_month2 2008):$(days_of_month 2 2008)" 

 

文件:test_datetime.txt

 

Text代码 

当前时间(date):六 2 27 15:58:28CST 2010 

昨天(yesterday):2010-02-26 

今天(today):2010-02-27 

现在(now):2010-02-27 15:58:28.734817000 

现在(curtime):2010-02-27 15:58:28 

上月(last_month):2010-01 

上月(last_month_packed):201001 

上月第一天(first_date_of_last_month):2010-01-01 

上月最后一天(last_date_of_last_month):2010-01-31 

今天星期几(day_of_week):6 

上个小时(last_hour):2010-02-27-14 

当前的小时(the_hour):15 

当前的分钟(the_minute):58 

当前的秒钟(the_second):28 

当前的年份(the_year):2010 

当前的月份(the_month):2 

当前的日期(the_date):27 

前天(days_ago 2):2010-02-25 

明天(days_ago -1):2010-02-28 

后天(days_ago -2):2010-03-01 

十天前的日期(days_ago 10):2010-02-17 

中文的日期星期(chinese_date_and_week):227星期六 

随机数字(rand_digit):5 

随机数字(rand_digit):9 

1970年来的秒数(seconds_of_date):1267257508 

1970年来的秒数(seconds_of_date 2010-02-27):1267200000 

1970年来的秒数(seconds_of_date 2010-02-27 15:53:21):1267257201 

1970年来的秒数对应的日期(date_of_seconds 1267200000):2010-02-27 

1970年来的秒数对应的日期时间(datetime_of_seconds 1267257201):2010-02-2715:53:21 

2008年是闰年 

2007 02 03日期合法 

2007 02 28日期合法 

20102月的天数(days_of_month2 2010):28 

20082月的天数(days_of_month2 2008):29 

        

 

#!/bin/bash

str="hello,world,i,like,you,babalala"

arr=(${str//,/ })

for i in ${arr[@]}

do

   echo$i

done

位操作: