shell 的基本元素
#!/bin/bash(shell) 指出解释本程序的shell
#注释
变量
控制
一般步骤:编辑文件,保存文件,将文件赋予可执行的权限,运行及排错
一般以.sh为文件后缀。没有也能执行。
执行方式:./filename sh run.sh
shell的一般结构
shell类型
函数
function funcname()
{
}
主过程
第一句可执行的shell命令开始
一般模板
特殊符号
#注释
$变量符
‘’所有字符原样输出
` `内部的字符串作为shell命令解释
\把特殊字符变成普通字符。就是在特殊字符前加\该字符用于原样输出。
“”内部的$ 、\、`保留特殊功能,其他作为普通字符
变量
本地变量:
shell脚本文件内使用;
变量名(区分大小写)=值(无空格);
弱类型,不需要声明类型
$变量名 #${变量名}
unset 变量名 #清除变量名 set命令可以显示所有的本地变量名
设置只读变量:readonly 变量名
环境变量:
在shell中直接使用,可以加以修改
设置环境变量:variable-name=value
export variable-name
显示环境变量名:env 可以看到所有的变量名, echo $环境变量名
清除环境变量名 : unset $变量名
HOME/SHELL/PWD/HISTSIZE/ENV/MAIL/PATH/LANG/(理解环境变量,追加 PATH=$NEW_ADD_PATH:$PATH)
理解各个配置文件生效的时机:
/etc/profile 用户登录时执行一次,每次登录都会执行
~/.bash_profile 用户登录时仅仅执行一次(新的环境变量,一般放在此文件的末尾)
~/.bashrc 打开新的shell,执行,并会调用 /etc/bashrc
/etc/bashrc 使用bash shell 是会被执行
~/.bash_login ~/.profile
内部变量:系统提供,不可修改
$# 传入shell脚本的参数的数量
$? 获得最后命令的完成码
$0 shell函数的名称
$*脚本全部参数的单字符串
$@ “参数1”“参数2”以此形式保存的脚本的入参
$n第N个参数
$!上一个命令的PID
$$本程序的PID
位置参数
1 2 3 # $1 $2 $3 $0是脚本的文件名
变量表达式
test N1 -参数 N2 真 返回0,假返回1 #可以用[N1 -lt N2]代替前式
-lt 小于
-le小于等于
-gt大于
-ge大于等于
-eq等于
-ne不等于
整数判断
test 1 -lt 4
echo ?
文件测试
-f 文件
-d 目录
-s 长度大于0
-r 可读
-w 可写
-x 可执行
if[ -x $1] #传入的第一个文件是否可执行
字符串测试
test s #s非空
test s1=s2
test s1!=s2
test -z s 长度为0
其他参数
-a 与
-o或
!非
控制流程
分支循环控制
分支结构
if
if[ $# -eq 0]
then echo "input 0 parameter"
elif[ $# -gt 1]
then echo "input more than 1parameter"
else echo "input 1parameter"
fi
case
case "$#" in
0) echo "input 0 parameter";;
1) echo "input 1parameter;;
*)echo "input more than 1 parameter";;# 不要忘记两个分好
esac #case逆序
for
for i in `seq 1 9` # 赋值给变量i
do
echo $(expr $i \* 10) # 1-9 乘以十 10 20 30 40 50 60 70 80 90
done
read
read parameter1 [patameter2 ...]
用于从键盘读取值, 用空格或者table 作为分割
如果输入的数据不够,不够的用空填补
如果过多, 最后一个将接受所有的输入
read a b
for i in `seq $a $b`
do
echo $(expr $i \* 10)
done
while
i=1
sum=0
while[$i -le 100]
do
sum=$[$sum+$i]
i=$[$i=1]
done
echo $sum
命令结果重定向
1 标准输出
2标准错误输出
>/dev/null 2>&1
2>&1 错误输出重定向到标准输出
>/dev/null 标准输出重定向到空
command >file 2>file
command >file 2>&1
方式1:打开file两次,错误输出和标准输出会相互覆盖
方式2:错误先输出都标准输出,标注输出再输出到file中
cat <file >file #>file 先清空内容,然后再去读,导致为空
实例
判断用户是否已经在系统中登录
#!/bin/sh
if test $# -ne 1
then
echo "Incorrect number of arguments"
echo "Usage:ifuser username"
else
user=$1
if who | grep -q $user
then #利用管道,查找已登录的用户名 中,是否包含$user
echo $1 "user is logged on."
else
echo $1 "user is not logged on."
exit 1
fi
fi
简单菜单功能
#!/bin/sh
clear
echo "------------------menu-----------------"
echo "1.find files modified in last 24 hours"
echo "2.the free disk space"
echo "3.space consumed by this user"
echo "4.exit"
echo
echo -n "---select:"
read choice
case $choice in
1)find $HOME -mtime -l -print;;
2)df;;
3)du -s $HOME;;
4)exit;;
*)echo "invalid option"
esac
expr 1+3 对表达式求值
seq 1-9:产生1-9的数字序列
seq
-f, --format=FORMAT use printf style floating-point FORMAT (default: %g)
% 前面制定字符串
seq -f "str%03g" 9 11
str009
str010
str011
-s, --separator=STRING use STRING to separate numbers (default: \n)
-s 指定分隔符 默认是回车
seq -s" " -f"str%03g" 9 11
str009 str010 str011
-w, --equal-width equalize width by padding with leading zeroes
-w 指定输出数字同宽 不能和-f一起用
seq -w -f"str%03g" 9 11
seq: format string may not be specified when printing equal width strings
seq -w 98 101
098
099
100
101