shell基础:
sh命令:
参数:
-c string 将string当作命令来执行。注意区别:string是用单引号扩起来的还上用双引号扩起来的!
-x xxx.sh 开启调试模式,shell在执行脚本的过程中把它实际执行的命令都显示出来,并且在命令的行首显示一个"+"号(shell内置变量PS4='+ '),同set -x。
补充:可以通过修改$PS4的值,从而使每一条实际执行的命令前面显示其行号以及所属的函数名。eg:先执行export PS4='+{$LINENO:${FUNCNAME[0]}} ', 然后再使用“-x”选项来执行脚本。
-n 不执行脚本,而是去读一遍脚本中的命令,目的是为了检查脚本中的语法错误。
# !/usr/bin/env bash
说明:脚本解释器在linux中可能被安装在不同的目录,而env可以在系统的PATH目录中查找,故脚本用env启动。
命令 -/+参数
-参数 设置某个参数
+参数 取消某个参数的设置。
set命令:
参数:
无参 列出所有的环境变量。
-e 当命令的返回值不等于0(即执行该命令报错)时,立即退出shell。
+e 表示取消-e参数,即当命令的返回值不等于0时,不会立即退出shell,而是会继续执行shell脚本。
-x 开启调试模式。
declare命令:
说明:用于声明shell变量
参数:
-r 将变量声明为只读变量。eg:declare -r name=jack
-x 将变量设置为环境变量,该变量可供shell以外的程序来使用。
echo命令:
参数:
-e 将特殊字符进行转义。
\a 发出警告声
\c 最后不加换行符号
\f 换行但光标仍旧停留在原来的位置
\n 换行且光标移至行首
\r 光标移至行首,但不换行
\t 插入tab
let命令:
说明:let命令是bash中用于计算的工具,用于执行一个或多个表达式,变量计算中不需要加上$来表示变量。如果表达式中包含了空格或其他特殊字符,则必须引起来。
举例:
let i=i+1
let i++
mail命令:
方式一:
在shell窗口中编辑内容,编辑完成后按ctrl+d退出编辑环境,邮件即可发送。
mail -s "邮件主题" jxn@speed.com
方式二:
mail -s "邮件主题" jxn@speed.com < content.txt
方式三:
echo "mail content" | mail -s "邮件主题" jxn@speed.com
补充:
ctrl+c 终止当前任务命令或程序。
ctrl+d 退出当前用户环境,相当于exit。
exit命令:
如果在管道中使用exit,则只会退出当前管道,并不会退出整个脚本进程。
命令行参数
$0 脚本的名字
$1, $2, ..., $9 脚本第1个到第9个命令行参数
$# 命令行参数的个数
$* 以“参数1 参数2 参数3..” 的形式返回所有命令行参数的值
$@ 以“参数1”“参数2”“参数3”.. 的形式返回所有命令行参数的值
$? 最后一条命令的退出状态码(执行成功返回0,执行失败返回1)
$$ 正在执行的进程的ID(PID)
getopts命令:
概念:获取命令行的参数。
格式:getopts argString varName
说明:
1)参数后面加冒号表示该参数可以接受赋值。
2)若argString以冒号开头,则表示忽略错误。eg:
若argString为 a: 那么,a必须赋值,否则会报错。
若argString为 :a: 那么,a即使不赋值,也不会报错。
使用:
while getopts :i:na: opt
do
case ${opt} in
i) echo 'this is param i value '$OPTARG
;;
n) echo 'has param n'
;;
a) echo 'this is param a value '$OPTARG
;;
esac
done
# 验证:sh my.sh -i 99 -n -a asdf
变量:
引用变量:
${variable}
$variable
清除变量:
unset variable
变量替换
$variable 保存在variable中的值
${variable} 保存在variable中的值
${variable:-string} 如果variable的值非空,则值为variable,否则值为string
${variable:+string} 如果variable的值非空,则值为string,否则值为空
${variable:=string} 如果variable的值非空,则值为variable,否则值为string且variable的值设置为string
${variable:?string} 如果variable的值非空,则值为variable,否则显示string并退出
引号的说明【重要】:
单引号括起来的的字符都作为普通字符对待。
双引号括起来的字符,除$、\、'(单引号)、"(双引号)之外,其余字符作为普通字符对待。
反引号括起来的字串被shell解释成命令,在执行时,shell首先执行该命令,并以它的标准输出结果取代整个反引号部分。
将命令的执行结果赋值给变量:
# 将某个shell命令的执行结果赋给某个变量。注:赋值号“=”的左右两边不能直接跟空格,否则shell会将其视为命令。
variableName=`command`
variableName=$(command)
定义系统提示符的变量
eg:PS1='[\u@\t \w]\$ '
\u:显示当前用户名
\h:显示简写主机名。如默认主机名“localhost”
\$:提示符。如果是root用户会显示提示符为“#”,如果是普通用户会显示提示符为“$”
\w:显示当前所在目录的完整名称
\W:显示当前所在目录的最后一个目录
\t:显示24小时制时间,格式为“HH:MM:SS”
\T:显示12小时制时间,格式为“HH:MM:SS”
\d:显示日期,格式为“星期 月 日”
\A:显示24小时制时间,格式为“HH:MM”
\#:执行的第几个命令
字符串函数:
${#str} 获取字符串的长度
${str:num1:num2} 表示从字符串的第num1个字符开始,截取num2个字符。
${str/str1/str2} 将第一个str1替换为str2
${str//str1/str2} 将所有的str1替换为str2
${str#*pattern} 删掉第一个pattern及其左边的字符串
${str##*pattern} 删掉最后一个pattern及其左边的字符串
${str%pattern*} 删掉最后一个pattern及其右边的字符串
${str%%pattern*} 删掉第一个pattern及其右边的字符串
说明:#是去掉左边,%是去掉右边(tip:键盘上#在%的左边)、单一符号是最小匹配,两个符号是最大匹配。
数组:
定义:shell中的数组用括号来表示,元素之间用空格分隔。
初始化:
方式一:myArray=(element1 element2 element3)
举例:将一个只有一列数据的文件中的数据初始化到数组中:myArray=(`cat /data/mydata.txt`)
方式二:
myArray[0]=element1;
myArray[1]=element2;
myArray[2]=element3;
获取数组的元素:
${myArray[index]} 获取下标为index的数组
${myArray} 或 ${myArray[0]} 获取数组的第一个元素
${myArray[*]} 或 ${myArray[@]} 获取数组的所有元素
${#myArray[*]} 获取数组的长度
条件判断:
概念:表达式用中括号[]或双中括号[[]]括住,条件表达式与左右方括号之间必须都保留一个空格。
说明:单中括号中的变量必须要加双引号,双中括号中的变量不用加双引号。
举例:[ -z "$pid" ] VS [[ -z $pid ]]
参数:
逻辑运算符:
&& expr1 && expr2 逻辑与(短路与)
|| expr1 || expr2 逻辑或(短路或)
! 逻辑非
数值判断:
-eq num1 -eq num2 是否相等
-ne num1 -ne num2 是否不相等
-gt num1 -gt num2 是否大于
-ge num1 -ge num2 是否大于等于
-lt num1 -lt num2 是否小于
-le num1 -le num2 是否小于等于
字符串判断:
= str1 = str2 字符串是否相等,注意:"="两边必须有空格!
!= str1 != str2 字符串是否不等
-n -n str1 字符串是否非空
-z -z str2 字符串是否是空串(长度是否等于0 z:zero)
文件判断:
-e -e filenaem 文件是否存在
-r -r filename 文件是否存在且可读
-w -w filename 文件是否存在且可写
-s -s filename 文件是否存在且长度非0
-f -f filename 文件是否存在且是普通文件
-d -d filename 文件是否存在且是一个目录
-L -L finename 文件是否存在且是一个链接
循环:
格式:
while [ condition ]
do
# do something
done
无限循环:
while :
do
# do something
done
读文件:
# 方式一:read通过输入重定向,把file的第一行所有的内容赋值给变量line,循环体内的命令一般包含对变量line的处理;然后循环处理file的第二行、第三行。。。一直到file的最后一行
while read line
do
# do something
done < file
# 方式二:command命令的输出作为read循环的输入,这种结构常用于处理超过一行的输出。
command | while read line
do
# do something
done
举例1:
#!/usr/bin/env bash
# 从数据库中导出的数据,每行数据以制表符分隔
path=/home/jxn/updateData.tsv
# 计数
count=0;
echo "--------- start"
# 按行读取文件的内容
while read line
do
# 将每行的内容转换为数组
dataArray=(${line});
firstFieldValue=${dataArray[0]};
secondFieldValue=${dataArray[1]};
updatesql="update mytable set firstField=\"${firstFieldValue}\" where secondField=\"${secondFieldValue}\"";
# 执行sql
echo sql=${updatesql};
result=`/home/jxn/tools/mysql -h myhost -P 3306 -uroot -p'root!@#' dbName -e "${updatesql}"`;
# 计数
let count=count+1;
echo "---------result=[${result}] count=[${count}] "
done < ${path}
echo "--------- end"
举例2:
#!/usr/bin/env bash
# 文件中每行数据以英文逗号分隔
# 如果文件最后一行之后没有换行符\n,则read读取最后一行时遇到文件结束符EOF,循环即终止。从而导致最后一行无法读取!!! 而for line in $(cat 文件名) 方式文件最后一行没有换行符也可以读取到。
path=/d/数据文件.txt
# 计数
count=0;
# 按行读取文件的内容,并输出拼接的sql文件
while read line
do
# 将每行的内容转换为数组
firstFieldValue=`echo ${line} | awk -F ',' '{print $1}'`;
secondFieldValue=`echo ${line} | awk -F ',' '{print $2}'`;
updatesql="update xxx set xx='${secondFieldValue}' where myField='${firstFieldValue}';";
# 执行sql
echo ${updatesql} >> execute.sql;
# 计数
let count=count+1;
echo "---------count=[${count}] "
done < ${path}
举例3:
#!/usr/bin/env bash
# 对文件中的每行数据进行处理后,通过管道输出。
for line in $(cat mydata.txt);
do
printf $line | awk '{print $1}'; # 注意,这里需要分号结尾。
done | sort | uniq -c > result.txt
shell基础笔记
于 2014-11-22 23:58:21 首次发布