首页 > 代码库 > linux bash shell学习笔记
linux bash shell学习笔记
Bash
开头#!/bin/bash。echo语句屏蔽“”若使用则 \” \”。即使文件没有执行权限,仍然可以通过bashhello.sh或者 sh hello.sh来执行文件。
标准输出写入>>文件中,标准错误输出默认为屏幕。标准错误输出为2>>。错误和输出都写入文件:1>>log 2>>err。两者都写入同一个文件:>&all_result,> all_result 2>& 1。
赋值:[root@host1 ~]#my=‘hello‘ ‘=‘左右两边都不能有空格;标准调用变量${}.BASH中的变量既然不需要定义,也就没有类型一说,一个变量即可以被定义为一个字符串,也可以被再定义为整数。如果对该变量进行整数运算,他就被解释为整数;如果对他进行字符串操作,他就被看作为一个字符串.
数值计算:+号两边不能有空格。Let x=${x}+1。Let “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列分钟1~59
第2列小时1~23(0表示子夜)
第3列日1~31
第4列月1~12
第5列星期0~6(0表示星期天)
第6列要运行的命令
0,30 18-23 * * * 每天18 : 00至23 : 00之间每隔30分钟
45 4 1,10.,22 * * 上面的例子表示每月1、10、22日的4 : 45
10 1 * * 6,0 每周六、周日的1 : 10
* */1 * * * 每小时
* 23-7/1 * * * 晚上11点到早上7点之间,每隔一小时
*/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
#昨天
#比如今天是2010年2月27日,那么结果就是2010-02-26
yesterday()
{
date --date=‘1 day ago‘ +%Y-%m-%d
}
# usage: today
#今天
#比如今天是2010年2月27日,那么结果就是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
#取上个月的第一天
#比如本月是2010年2月,那么结果就是2010-01-01
first_date_of_last_month()
{
date --date=‘1 month ago‘ ‘+%Y-%m-01‘
}
# usage: last_date_of_last_month
#取上个月的最后一天
#比如当前是2010年2月,那么结果就是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()
#打印中文的日期和星期
#比如:2月27日星期六
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>
#获取yyyy年mm月的天数,注意参数顺序
#比如: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 "2010年2月的天数(days_of_month2 2010):$(days_of_month 2 2010)"
echo "2008年2月的天数(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):2月27日星期六
随机数字(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日期合法
2010年2月的天数(days_of_month2 2010):28
2008年2月的天数(days_of_month2 2008):29
#!/bin/bash
str="hello,world,i,like,you,babalala"
arr=(${str//,/ })
for i in ${arr[@]}
do
echo$i
done
位操作: