循环
for循环
通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环
格式1
[java] view plain copyfor ((i=0;i《10;i++))
do
。。。
Done
格式2
[java] view plain copyfor i in 0 1 2 3 4 5 6 7 8 9
do
。。。
Done
格式3
[java] view plain copyfor i in {0..9}
do
。。。
done
注意:for i in {0..9} 等于for i in {0..9..1} , 第三个参数为跨步。
例如:
{0..9..2} 表示 0,2,4,6,8
while循环
适用于循环次数未知,或不便用for直接生成较大的列表时
格式:
[java] view plain copywhile 测试条件
do
循环体
done
如果测试条件为“真”,则进入循环,测试条件为假,则退出循环。
打印结果为0~9.
循环控制
循环控制命令——break
break命令是在处理过程中跳出循环的一种简单方法,可以使用break命令退出任何类型的循环,包括while循环和for循环
循环控制命令——continue
continue命令是一种提前停止循环内命令,而不完全终止循环的方法,这就需要在循环内设置shell不执行命令的条件
条件
bash条件测试
格式:
[java] view plain copytest EXPR
[ EXPR ]:注意中括号和表达式之间的空格
整型测试:
-gt:大于:
-lt:小于
-ge:大于等于
-le:小于等于
-eq:等于
-ne:不等于
例如[ $num1 -gt $num2 ]或者test $num1 -gt $num2
字符串测试:
=:等于,例如判断变量是否为空 [ “$str” = “” ] 或者[ -z $str ]
!=:不等于
判断
if判断:
单分支
[java] view plain copy if 测试条件;then
选择分支
fi
双分支
[java] view plain copyif 测试条件
then
选择分支1
else
选择分支2
fi
多分支
[java] view plain copyif 条件1; then
分支1
elif 条件2; then
分支2
elif 条件3; then
分支3
。。。
else
分支n
i
双分支示例:
Case判断
有多个测试条件时,case语句会使得语法结构更清晰
格式:
[java] view plain copycase 变量引用 in
PATTERN1)
分支1
;;
PATTERN2)
分支2
;;
。。。
*)
分支n
;;
esac
PATTERN :类同于文件名通配机制,但支持使用|表示或者
a|b:a或者b
*:匹配任意长度的任意字符
?:匹配任意单个字符
[a-z]:指定范围内的任意单个字符
示例:
算术运算
[java] view plain copylet varName=算术表达式
varName=$[算术表达式]
varName=$((算术表达式))
varName=`expr $num1 + $num2`
使用这种格式要注意两个数字和+号中间要有空格。
示例:
逻辑运算符
if [ 条件A && 条件B ] 在shell中怎么写?
if [ 条件A && 条件B ];then 是不对的
解决方法:
(1)需要用到shell中的逻辑操作符
-a 与
-o 或
! 非
如if [ 条件A -a 条件B ]
(2)if [ 条件A ] && [条件B ]
(3)if((A&&B))
(4)if [[ A&&B ]]
自定义函数
格式:
[java] view plain copyfunction 函数名(){
。。。
}
引用自定义函数文件时,使用source func.sh
有利于代码的重用性
函数传递参数(可以使用类似于Java中的args,args[1]代表Shell中的$1)
函数的返回值,只能是数字
read
read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。
格式
[java] view plain copyread VAR_NAME
read如果后面不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中
[java] view plain copy#表示输入时的提示字符串:
read -p “Enter your name:” VAR_NAME
[java] view plain copy# -t表示输入等待的时间
read -t 5 -p “enter your name:” VAR_NAME
[java] view plain copy# -s 表示安全输入,键入密码时不会显示
read -s -p “Enter your password: ” pass
declare
用来限定变量的属性
-r 只读
-i 整数:某些算术计算允许在被声明为整数的变量中完成,而不需要特别使用expr或let来完成。
-a 数组
示例:
字符串操作
获取长度:
[java] view plain copy${#VAR_NAME}
字符串截取
[java] view plain copy${variable:offset:length}或者${variable:offset}
取尾部的指定个数的字符
[java] view plain copy${variable: -length}:注意冒号后面有空格
大小写转换
小--》大:
[java] view plain copy${variable^^}
大--》小:
[java] view plain copy${variable,,}
示例:
数组
定义:declare -a:表示定义普通数组
特点
支持稀疏格式
仅支持一维数组
数组赋值方式
一次对一个元素赋值a[0]=$RANDOM
一次对多个元素赋值a=(a b c d)
按索引进行赋值a=([0]=a [3]=b [1]=c)
使用read命令read -a ARRAY_NAME查看元素
[java] view plain copy${ARRAY[index]}:查看数组指定角标的元素
${ARRAY}:查看数组的第一个元素
${ARRAY[*]}或者${ARRAY[@]}:查看数组的所有元素
获取数组的长度
[java] view plain copy${#ARRAY[*]}
${#ARRAY[@]}
获取数组内元素的长度
[java] view plain copy${#ARRAY[0]}
注意:${#ARRAY[0]}表示获取数组中的第一个元素的长度,等于${#ARRAY}
从数组中获取某一片段之内的元素(操作类似于字符串操作)
格式:
[java] view plain copy${ARRAY[@]:offset:length}
offset:偏移的元素个数
length:取出的元素的个数
${ARRAY[@]:offset:length}:取出偏移量后的指定个数的元素
${ARRAY[@]:offset}:取出数组中偏移量后的所有元素
数组删除元素:
[java] view plain copyunset ARRAY[index]
示例:
其他命令
date
显示当前时间
格式化输出 +%Y-%m-%d
格式%s表示自1970-01-01 00:00:00以来的秒数
指定时间输出 --date=‘2009-01-01 11:11:11’
指定时间输出 --date=‘3 days ago’ (3天之前,3天之后可以用-3)
示例:
后台运行脚本
在脚本后面加一个&
[java] view plain copytest.sh &
这样的话虽然可以在后台运行,但是当用户注销(logout)或者网络断开时,终端会收到Linux HUP信号(hangup)信号从而关闭其所有子进程
nohup命令
不挂断的运行命令,忽略所有挂断(hangup)信号
[java] view plain copynohup test.sh &
nohup会忽略进程的hangup挂断信号,所以关闭当前会话窗口不会停止这个进程的执行。
nohup会在当前执行的目录生成一个nohup.out日志文件
标准输入、输出、错误、重定向
标准输入、输出、错误可以使用文件描述符0、1、2引用
使用重定向可以把信息重定向到其他位置
ls 》file 或者 ls 1》file(ls 》》file)
lk 2》file(lk是一个错误命令)
ls 》file 2》&1
ls 》 /dev/null(把输出信息重定向到无底洞)
例子:
[java] view plain copycommand 》/dev/null 2》&1
Crontab定时器
linux下的定时任务
编辑使用crontab -e
一共6列,分别是:分 时 日 月 周 命令
查看crontab执行日志
[java] view plain copytail -f /var/log/cron
必须打开rsyslog服务cron文件中才会有执行日志(service rsyslog status)
[java] view plain copytail -f /var/spool/mail/root(查看crontab最近的执行情况)
查看cron服务状态
[java] view plain copyservice crond status
启动cron服务
[java] view plain copyservice crond start
小结及示例:
基本格式 :
* * * * * command
分 时 日 月 周 命令
第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令
crontab文件的一些例子:
30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启apache。
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启apache。
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启apache。
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。
0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重启apache。
* */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启apache
* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
晚上11点到早上7点之间,每隔一小时重启apache
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启apache
0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启apache
ps和jps
ps:用来显示进程的相关信息
ps显示当前shell启动的所有进程
ps -e显示系统中所有进程
ps -ef|grep java
jps:类似linux的ps命令,不同的是ps是用来显示所有进程,而jps只显示java进程,准确的说是显示当前用户已启动的部分java进程信息,信息包括进程号和简短的进程command。
问题:某个java进程已经启动,用jps却显示不了该进程进程号,使用ps -ef|grep java却可以看到?
java程序启动后,默认(请注意是默认)会在/tmp/hsperfdata_userName目录下以该进程的id为文件名新建文件,并在该文件中存储jvm运行的相关信息,其中的userName为当前的用户名,/tmp/hsperfdata_userName目录会存放该用户所有已经启动的java进程信息。而jps、jconsole、jvisualvm等工具的数据来源就是这个文件(/tmp/hsperfdata_userName/pid)。所以当该文件不存在或是无法读取时就会出现jps无法查看该进程号。
原因:1,磁盘读写、目录权限问题。2,临时文件丢失,被删除或是定期清理。3,java进程信息文件存储地址被设置,不在/tmp目录下
登录Shell和交互shell
交互式的:顾名思义,这种shell中的命令时由用户从键盘交互式地输入的,运行的结果也能够输出到终端显示给用户看。
非交互式的:这种shell可能由某些自动化过程启动,不能直接从请求用户的输入,也不能直接输出结果给终端用户看。输出最好写到文件。比如使用Shell脚本。
登录式:意思是这种是在某用户由/bin/login登陆进系统后启动的shell,跟这个用户绑定。这个shell是用户登陆后启动的第一个进程。login进程在启动shell时传递第0个参数指明shell的名字,该参数第一个字符为“-”,指明这是一个login shell。比如对bash而言,启动参数为“-bash”。
非登录式:不需login而由某些程序启动的shell。传递给shell的参数,是没有‘-’前缀的。还以Bash为例,当以非login方式启动时,它会调用~/.bashrc,随后~/.bashrc中调用/etc/bashrc,最后/etc/bashrc调用所有/etc/profile.d目录下的脚本。
一旦打开一个交互式login shell,或者以--login选项登录的非交互式shell,都会首先加载并执行/etc/profile中的命令,然后再依次加载~/.bash_profile, ~/.bash_login, 和~/.profile中的命令。
当bash以login shell启动时,它会执行/etc/profile中的命令,然后/etc/profile调用/etc/profile.d目录下的所有脚本;然后执行~/.bash_profile,~/.bash_profile调用~/.bashrc,最后~/.bashrc又调用/etc/bashrc。要识别一个shell是否为login shell,只需在该shell下执行echo $0。
注意: /etc/profile中的设置只对Login Shell生效,而crontab运行脚本的shell环境是non-login的,不会加载/etc/profile的设置。
评论
查看更多