Shell基础

Shell

1 Vi的基本操作

1.1 保存退出

# vi的基本模式切换
# 退出
:q!		不保存强制退出
:wq		保存退出
:w		保存不退出
# 命令行模型
zz/zq 	保存/不保存退出

1.2 编辑—命令模式

# 新增
a:	光标后面开始填写
A:	光标这行最后面开始
i:	光标所在位置开始		
I:	光标所在行第一个非空白开始
o:	光标所在行下新增一行开始
O:	关闭所在行上新增一行开始
# 删除
x:	删除光标所在字符
dw:	删除一个单词
dd:	删除光标所在的行
s:	删除光标所在字节,进入输入输出模型
#删除指定数字
3x:	删除3个字符
3dw:删除3个单词
3dd:删除3行(往下数两行)
# d加光标键
左:删除光标前面的字符
右:删除光标所在的字符
上:将当前行与上一行删除
下:当前行与下一行删除
# 恢复
u	恢复刚才被修改的文本
U	恢复光标所在行的所有修改
.	重复上一次命令的操作
# 复制 粘贴
yy	复制整行
yw	复制光标所在单词
nyw 复制光标所在后面的n个单词
nyy 复制光标所在n行
p	粘贴
光标移动
h,j,k,l
nG 移动到N行行首
# 查找替换
:/string  # 搜索指定字符串
	按键n继续进行收索
# 替换
:%s 	/target01/target02 将文档中所有的target01替换成target02
:#,# 	s/target01/target02/g #表示数字 从#行到#行替换target01为target02
:s      /target01/target02/g 当前光标行中将target01替换target02

# 全局配置vi
配置文件 /etc/vim/cimrc 或者/etc/vimrc
配置文件位"./vimrc"
set nu				显示行号
set ruler			显示光标位置
set undolevel		显示光标位置
set smartindent		智能缩进
syntax on			语法高亮

2 Shell

2.1 Shell的基本元素

1. #! /bin/bash 指出shell类型
2. # 注释
3. 变量
4. 控制

2.2 第一个shell脚本

#! /bin/bash
echo "hello world"

2.3 注意点

1. 开头指明/bin/bash及解释器
2. 权限一般755有执行权限才可以./去执行
#!/bin/bash
# a simple shell script example
# a function
function sayhello
{
	echo "Enter Your name:"
	read name
	echo "Hello $name"
}
echo "programme starts here..."
sayhello
echo "programme ends."

2.4 Shell中的特殊字符

1. # 注释符号 
	除了 #!/bin/bash
2. $ 美元符号
	变量符号,与用$定义后面的普通字符作为变量名,字符长度超过1个时,{}
3. 单引号,双引号
	被引号引起来的全部是普通字符串
    echo 'filename / $ .'   ---> filename / $ .
    双引号除了$ / `其余里面全是特殊字符
    echo "filename `"    -----> ">"
4. 反斜杠 \  
	将后面的字符当普通字符对待
    echo 'filename \`'           ->>>>filename \`
    双引号是转义,单引号是普通字符
    echo "filename \`"          ->>>>filename `

2.5 Shell中的变量

本地变量
	局部变量,只有在创建的时候使用,在程序里面可以随意修改
环境变量
	可以在创建他们的Shell及其派生出来的任意子程序中使用,有些是系统的变量可以直接使用
内部变量
	由系统提供,用户不能修改
2.5.1 本地变量
在用户现在的Shell生命周期的脚步中使用
变量名=# 1. 等号两边不可有空格
# 2. 取值包含空格,必须用双引号括起来
# 3. Shell变量可以用大小写字母,区分大小写

#变量的生命及使用
1. 变量是弱类型不用生命数据类型
2. 变量声明直接
	变量=值
3. 变量的引用
	$变量名    一个
	${变量名}  多个
4. 清除变量名
	unset 变量名
5. 设置只读的变量
	变量名=readonly 变量名
	例如:
	free=book
	echo ${free}
	readonly free
	free=www   ------->bash: free:只读变量
	
2.5.2 环境变量
环境变量用于所有用户进程,登陆进程称父进程,通过pstree查看
1. 环境变量可以用于所有的子程序,包括编辑器,脚本,应用
2. 环境变量可以早命令行中设置,但是用户注销时值会丢失
3. 环境变量均为大写
4. 必须用export命令导出

# 设置环境变量
variable-name=value
export variable-name(环境变量名大写)
#显示环境变量
env 可以看到所有的环境变量
echo $环境变量名
#清除环境变量
unset 环境变量名称
HOME	代表使用者的家目录。
PSI		shell的主提示符
SHELL	目前这个环境使用的shell哪个程序
PWD		用户当前工作目录的路径
HISTSIZE曾经下达过的指令可以被系统记录下来,而记录的数目由这个值来确定
ENV		个性化环境设置文件的读取文件
MAIL	mail受信时,系统会去读取的邮件信箱邮件
PATH	执行文件搜寻的路径,目录与目录之间用:隔开
LANG	语言系文件
Bash初始化的配置文件有
/etc/profile	
	# 存放全局变量
~/.bash_pofile	
	# 使用该文件输入专门用于自己使用的shel信息
~/.bash_login
	
~/.profile
	
~/.bashrc
	# 专用于bash shell的bash信息
/etc/bashrc
	#为每一个运行bash shell的用户执行此文件
	
登陆linux 
1. 先启动/etc/profile配置文件,为系统的每个用户设置环境信息
2. ~/.bash_pofile 每个用户的shell信息
3. ~/.bashrc 登陆及每次打开新的shell都会执行
2.5.3 内部变量
内部变量是linux所提供的一种特殊类型的宾利,在shell程序内这类变量的值是不能修改的
部分内部变量
$#		传送给shell程序的位置参数的数量
$?		最后命令的完成码或者在Shell程序内部执行的shell程序
$()		shell程序的名称
$*		调用shell程序时所传送的全部参数的单字符串
$@		参数1 参数2 参数3
$n		第n个参数
$$		本程序的PID
$!		上一个命令的PID

例如:hello.s
echo "当前程序的名字是$0"
echo "共输入$#个参数,全部参数是$@,第一个参数是$1"
echo "当前程序进程的pid是$$"
echo "执行完毕,返回$?"

输入sh hello.s hello world ok 
执行结果
当前程序的名字是hello.s
共输入3个参数,全部参数是hello world ok ,第一个参数是hello
当前程序进程的pid是5303
执行完毕,返回ok

2.6 Shell中的参数

2.6.1 位置参数
1. 位置参数及其引用,按照输入参数的位置写入参数
# 用$1 $2 来获取传进来的参数
2. 用set命令为位置参数赋值
格式 set [参数表]

2.7 变量表达式

1. 条件判断命令
格式 test number01 -参数 number02 真返回0 假返回1
-lt		小于
-le		大于等于
-gt		大于
-ge		大于等于
-eq		等于
-ne		不等于

eg:
test 100 -gt 10000  100大于1000吗
echo $?
1 假
2. 文件测试
-f	存在且是普通文件
-d	存在且是目录
-s	存在且字节数大于0
-r	存在且可读
-w	存在且可写
-x	存在且执行
3. 字符串测试
test s 字符串s非空
test s1==s2
test s1!=s2
test -Z s  字符串长=0,及空
test -n 字符串长>0

4. 其他参数
	-a 逻辑与
	-o 逻辑或
	! 逻辑非

2.8 控制流程

seq命令 产生1-9的数值序列
比如 seq 14 
expr命令: 对表达式求职
[] 直接对被括起来的表达式求职

eg:
expr 1 + 3 --->4
expr 2 \* 3 ---> 6乘号需要转义
数字和运算符中间要有空格
条件判断语句
if [ $# -eq 0 ]
then 
	echo "输入0个参数"
elif [ $# -lt 1 ]
then
	echo "输入了多个参数"
else
	echo "输入1个参数"
fi
case "$#" in
	0) echo "输入了0个参数";;
	1) echo "输入了1个参数";;
	*) echo "输入了2个参数";;
esac
每个分支后面加;结尾
for i in `seq 1 9`
do
	echo `expr $i \* 10`
done
或写 echo $(expr $i \* 10)
乘号前面加转义,
与数字之间要有空格
read 变量1 变量2
	1. 可以从键盘上读取多个变量的值,用户输入数据时,以空格或者tab键隔开
	2. 如果输入的数据个数不够,按位置对应,后面的补空对其
	3. 如果输入的数据过多,最后一个变量被赋予所有的数据
read a b
for i in `seq $a $b`
do
	echo `expr $i \* 10`
done
# 输出a到b序列数各数的10倍数
while例子
i = 1
sum=0
while [ $i -le 100 ]
do
 	sum=$[$sum+$i]
 	i=$[$i+1]
 done
 echo $sum
2.8.1 while
#!/bin/bash
int=1
while(( $int<=5 ))
do
	echo $int
	let "int++"
done

echo '按下 <CTRL-D> 退出'
echo -n '输入您喜欢的网站名:'
while read FILM
do
	echo "是的! $FILM是一个好网站"
done

2.8.2 until
#!/bin/bash

a=0

until [ ! $a -lt 10 ]
do
	echo $a
	a=`expr $a + 1`
done


2.8.3 for
#!/bin/bash
for loop in 1 2 3 4 5 6
do
	echo "The value is:$loop"
done

for str in 'this is a string'
do
	echo $str
done


2.8.4 case
echo "输入1到4之间的数字:"
echo '你输入的数据为:'
read aNum
case $aNum in
	1) echo "你选择了1"
	;;
	2) echo "你选择了2"
	;;
	3) echo "你选择了3"
	;;
	4) echo "你选择了4"
	;;
	*) echo "你没有输入1到4之间的数字"
	;;
esac

2.9 命令结果重定向

1. stdout 标准输出
2. stderr 标准错误

2.10 屏蔽命令的任何输出

>/dev/null 2>&1
cp /etc/my.conf >/dev/null 2>&1
结果:什么也没有输出
/dev/null 空设备

#结果
1. cp命令没有目标文件,应该输出错误
2. 2>&1错误重定向指向标准输出
3. >/dev/null 又使标准输出重定向到空,就是不要输出信息
总结就是:一个错误的命令执行,什么功能都没有实现,且没有任何信息或错误输出

# 例如
1. command >file 2>file
2. command >file 2>&1
# 结果都是没有任何输出
# 1. 这种写法,stdout,stdree都会直接送到file中,会出现同时抢占file管道,file管道被打开两次,信息相互覆盖,两次io操作
# 2. 第二种写法,stdout会直接送file,stdree继承1的管道,往后面写,操作一次io
# io
cat < file > file   # 文件内容被清洗
cat file			# 没有内容
stdout ,stdree的管道会先准备号才会从stdin读取内容
> file 会先清洗file,然后再进< file,但是此时file内容为空
再定位读取file就会为空

2.11 小测试

1. 编写一个名为iffile的程序,它执行时判断/bin目录下data文件是否存在?
#!/bin/bash
# 判断和/bin目录下的文件是否存在
filename = /bin/data
if (test -f "$filename") then
	echo "exist"
else
	echo "not exist"
fi

1. 编写一个名为greet的问候程序,它执行时能更具系统当前的时间向用户问候信息。设从半夜到中午为早晨,中午到下午为6点为下午,下午6点为晚上
#!/bin/bash
export LANG="en_US.UTF-8"
h=`date|cut -c 17-18`
echo $h
if [ "$h" -ge 0 ] && [ "$h" -lt 12 ];
then
	echo "Good morning!"
elif [ "$h" -ge 12 ] && [ "$h" -lt 18 ];
then 
	echo "Good Afternoon!"
else
	echo "Good evening!"
fi

编写一个名为ifuser的程序,它执行时带用户名作为参数,判断该用户是否已经在系统登录,并给出相关信息
#!/bin/bash
if test $# -ne 1 then
echo "Incorrent number of arguments"
	echo "Usage:ifuser username"
else
	user=$1
	if who | grep -q $user 
	then
		echo $1 "user is logged on"
		exit 0
	else
		echo $1 "user is not  logged on"
		exit 1
	fi
fi

编写一个名为chname的程序,将当前目录下的所有.txt文件更名为.doc文件
#!/bin/bash
for file in *.txt
do
	leftname=`basename $file .txt`
	mv $file $leftname.doc
done

编写一个名为chuser的程序,执行中每隔5分钟检查指定用户是否登陆,用户名从命令行输入,如果指定的用户已经登陆则显示相关信息
#!/bin/bash
if test $# -ne 1
then 
	echo "Usage: chuser username"
else
	user="$1"
	until who |grep "$user" >/dev/null
	do
		sleep 300
	done
	echo "$user has logged on!"
fi

编写一个名为menu的程序,实现简单的弹出式菜单功能,用户能根据菜单项从键盘执行对应的命令
#! /bin/bash
clear
echo "-----------------------------MEUN------------------------- "
echo "    1.find files modified in last 24 hours                 "
echo "    2.The free disk space                                  "
echo "    3.Space consume by this user                           "
echo "    4.Exit                                                 "
echo
echo -n "    Select: "
read choice
case $choice in
1)find $HOME -mtime -1 -print;;
2)df;;
3)du -s $HOME;;
4)exit;;
*)echo "Invalid option"
esac

# 注意点
# 乱码的问题 
# 第一行加 export LANG="en_US.UTF-8"

2.12 shell 中的字符串操作

#!/bin/bash
your_name='runoob'
str="Hello,I know you are \"${your_name}\"! \n"
echo -e ${str}         # 使用字符串

str01="hello,${your_name}"
echo $str01            # 拼接字符串

str02="hello,"${your_name}
echo ${str02}		   # 拼接字符串

# 获取字符串长度
str03="ruoob is great site"
echo ${#str03}

# 提取字符串
strtest="ruoob is geat site" # 需要用bash执行脚本
echo ${strtest:1:4}  #提取第二个到第四个字符长度

# 查询子字符串
strtest01="ruoob is geat site" # 查找io的字符串 
echo `expr index "$strtest01" io`

2.13 shell中的数组操作

#!/bin/bash
my_array=(a b "c" d)
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2

# 读取数据
echo "第一个元素为: ${my_array[0]}"
echo "第二个元素为: ${my_array[1]}"
echo "第三个元素为: ${my_array[2]}"
echo "第四个元素为: ${my_array[3]}"

# 获取数组中所有元素
echo "数组中的元素为: ${my_array[*]}"
echo "数组中的元素为: ${my_array[@]}"

# 获取数组中的长度
echo "数组中的元素为: ${#my_array[*]}"
echo "数组中的元素为: ${#my_array[@]}"

2.14 shell中的运算符操作

2.14.1 算术运算操作
#!/bin/bash
# 这是算术运算符
a=10
b=20

#加法
val=`expr $a + $b`
echo "a + b : $val"

# 减法
val=`expr $a - $b`
echo "a - b : $val"

# 乘法
val=`expr $a \* $b`
echo "a * b : $val"

# 除法
val=`expr $b / $a`
echo "b % a : $val "

if [ $a != $b ]
then
	echo "a 不等于 b"
fi
2.14.2 关系运算操作
#!/bin/bash
# 关系运算符
a=10
b=20

# 等于
if [ $a -eq $b ]
then
	echo "$a -eq $b : a等于b"
else
	echo "$a -eq $b : a不等于b"
fi

#不等于 
if [ $a -ne $b ]
then
	echo "$a -ne $b: a不等于b "
else
	echo "$a -ne $b: a等于b"
fi

# 大于
if [ $a -gt $b ]
then 
	echo "$a -gt $b: a大于b"
echo
	echo "$a -gt $b: a小于等于b"
fi

# 大于等于
if [ $a -ge $b ]
then
	echo "$a -ge $b: a 大于等于 b"
else
	echo "$a -ge $b: a 小于 b"
fi

# 小于
if [ $a -lt $b ]
then
	echo "$a -lt $b:a 小于b"
else
	echo "$a -lt $b:a大于等于"
fi

# 小于等于
if [ $a -le $b ]
then
	echo "$a -le $b: a小于等于 b"
else
	echo "$a -le $b:a大于b"
fi
2.14.3 布尔运算
#!/bin/bash

a=10
b=20

if [ $a != $b ]
then
	echo "$a != $b :a不等于b"
else
	echo "$a == $b: a 等于b"
fi

if [ $a -lt 100 -a $b -gt 15 ]
then
	echo "$a 小于 100且 $b 大于15:返回true"
else
	echo "$a 小于 100且 $b 大于15:返回false"
fi

if[ $a -lt 100 -o $b -gt 100 ]
then
	echo " $a 小于100或 $b 大于100:返回true "
else
	echo "$a 小于100且$b大于100:返回false"
fi
2.14.4 字符串运算
#!/bin/bash

a="abc"
b="efg"

if [ $a = $b ]
then
	echo "$a = $b : a等于b"
else
	echo "$a = $b : a不等于b"
fi

if [ $a != $b ]
then
	echo "$a != $b: a不等于b"
else
	echo "$a != $b: a等于b"
fi

if [ -z $a ]
then
	echo "-z $a :字符串长度为0  "
else
	echo "-z $a :字符串长度不为0 "
fi

if [ -n "$a" ]
then
	echo "-n $a :字符串长度不为0"
else
	echo "-n $a :字符串长度为0"
fi

if [ $a ]
then
	echo "$a :字符串不为空 "
else
	echo "$a :字符串为空 "
fi

2.14.4 shell文件操作
#!/bin/bash
file="/home/dxc/桌面/test/bool01.sh"
if [ -r $file ]
then
	echo "文件可读"
else
	echo "文件不可读"
fi

if [ -w $file ]
then
	echo "文件可写"
else
	echo "文件不可写"
fi

if [ -x $file  ]
then
	echo "文件可执行"
else
	echo "文件不可执行"
fi

if [ -f $file ]
then
	echo "文件为普通文件"
else
	echo "文件不是普通文件"
fi

if [ -d $file ]
then
	echo "文件是个目录"
else
	echo "文件不是目录"
fi

if [ -s $file ]
then
	echo "文件不为空"
else
	echo "文件为空"
fi

if [ -e $file ]
then
	echo "文件存在"
else
	echo "文件不存在"
fi

2.15 函数

#!/bin/bash
demoFun(){
	echo "这是我的第一个shell函数"
}
echo "------函数开始执行-----"
demoFun
echo "------函数执行完毕-----"


# 带有返回值的函数
funWithReturn(){
	echo "这个函数会对输入的两个数字进行相加运算..."
	echo "输入第一个数字:"
	read aNum
	echo "输入的第二个数字:"
	read anotherNUm
	echo "两个数字和为 $aNum$anotherNUm !"
	return $(($aNum+$anotherNUm))
}
funWithReturn
echo "输入两个数字和为$?"

# 参数
funWithParam(){
	echo "第一个参数为$1 !"
	echo "第二个参数为$2 !"
	echo "第十个参数为$10 !"
	echo "第十个参数为${10} !"
	echo "第十一个参数为${11} !"
	echo "参数数有! $# 个"
	echo "作为一个字符串输出的所有参数 $*"

}
funWithParam 1 2 3 4 5 6 7 8 9 10 11 12

2.16 输入输出重定向

命令	说明
command > file		将输出重定向到 file。
command < file		将输入重定向到 file。
command >> file		将输出以追加的方式重定向到 file。
n > file			将文件描述符为 n 的文件重定向到 file。
n >> file			将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m				将输出文件 m 和 n 合并。
n <& m				将输入文件 m 和 n 合并。
<< tag				将开始标记 tag 和结束标记 tag 之间的内容作为输入。、
/dev/null 文件

#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com

cat << EOF
欢迎来到
菜鸟教程
www.runoob.com
EOF

2.17 文件包含


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值