首页 > 代码库 > shell 编程记录
shell 编程记录
Shell课程记录
作者:JCY
QQ1501614847
第一、常用命令Shell课程记录
作者:JCY
QQ1501614847
第一、常用命令
1、查看当前用户是否支持某条命令
#which [COMMAND...] 查看命令是否存在,如果存在会列出命令所在的位置。如果这条命令不存在,那么会列出所有的环境变量,告诉你在这么多目录中没有查找到该命令。
2、列出当前用户的环境变量
#echo $PATH
列出当前用户的所有的环境变量目录。
3、当前执行进程的名称
#echo $0
4、当前执行进程的PID
#echo $$
5、列出当前所在目录
#pwd
6、列出当前的用户名
echo $USER
7、上一条命令是否正常
#echo $?
返回0说明上一条命令正常,返回非零说明上一条命令错误
8、查看某个文件的内容
#tail -n 文件名
查看某个文件的最后n行。
9、列出目录下所有的文件以及子文件夹中的文件
#ls -l -F -R [路径]
不指定路径则为当前路径
10、添加用户
#adduser JCY1
成功后就会在/etc/passwd文件中会有一个JCY1用户信息表
11、删除用户
#deluser JCY1
成功后在/etc/passwd文件中没有了JCY1的用户信息表
12、更改JCY1用户的密码
#passwd JCY1 123456
13、列出所有的用户
#who
14、显示文件的行数,字数,字节数
wc命令的功能为统计指定文件中的字节数、字数、行数, 并将统计结果显示输出。
语法:wc [选项] 文件…
说明:该命令统计给定文件中的字节数、字数、行数。如果没有给出文件名,则从标准输入读取。wc同时也给出所有指定文件的总统计数。字是由空格字符区分开 的最大字符串。
该命令各选项含义如下:
- c 统计字节数。
- l 统计行数。
- w 统计字数。
这些选项可以组合使用。
输出列的顺序和数目不受选项的顺序和数目的影响。总是按下述顺序显示并且每项最多一列。
行数、字数、字节数、文件名
如果命令行中没有文件名,则输出中不出现文件名。
例如:
$ wc – lcw file1 file2
4 33 file1
7 52 file2
11 11 85 total
第二、标准输入输出向
1、标准输出重定向
cat命令用法
#cat test1.txt > test2.txt
test1.txt当中的内容把test2.txt覆盖掉,如果没有test2.txt会新建此文件,最终两个文件内容是一样的,并且是test1.txt的内容。
#cat test1.txt >> test2.txt
这种事追加写入,在test2.txt文件的后面继续添加test1.txt的全部内容
2、标准输入重定向
#passwd --stdin Jcy1 > /home/TestPwd.txt
从/home/TestPwd.txt文件的内容作为标准输入,如果/home/TestPwd.txt中的内容为6个字节“123456”。则给Jcy的用户设置密码为123456。
该命令就相当于#passwd Jcy1 123456
3、错误重定向
将中断出现的错误信息重定向其他的文件,假定当前目录下只有1.txt
#ls -l 1.txt 2.txt
该命令执行后会出现两种信息,一个真确的一个错误的。并且信息是在终端上显示。
#ls - 1.txt 2.txt >std.log 2>err.log
那么该目录下就会有两个文件了,std.log和err.log。那么错误信息就会在err.log中显示,正确信息就会在std.log中显示。
#ls - 1.txt 2.txt >std.log
正确信息写入了std.log,错误就会在终端显示。
若将上述的三条指令的>换成了>>,那么就会追加写入文件,否则在输出文件中只会显示最近一次的信息。
#ls -l 1.txt 2.txt &>err.log
终端会返回的无论正确的还是错误的都会显示在err.log文件中。
第三、shell脚本
1、脚本文件的内容包括
A、运行环境配置:#!/bin/bash独占首行,说明是使用bash来分析和执行脚本
B、注释信息:以#开头的说明性信息
C、可执行的linux命令。
2、执行脚本的方式
在执行脚本前要是脚本具有可执行的权限,使用#chmod 777 文件名
A、如果你在脚本文件所在目录,那么可以使用#./文件名
B、如果你在其他的目录下,那么可以使用#. 文件名完整路径
C、无论在那个路径下,可以使用#bash 文件名完整路径
D、无论在那个路径下,可以使用#sh 文件名完整路径
E、无论在那个路径下,可以使用#source 文件名完整路径
F、无论在那个路径下,可以使用#bash 文件名完整路径
3、例子测试
创建任务表需要使用crontab命令,对于该命令的用法请参考《linux创建计划任务表》这篇文章。在任务里面每隔2分钟就执行特定的脚本。任务表中添加如下任务:
*/2 * * * /home/bak.sh
bak.sh文件的内容如下:该内容是将/home/tem文件夹中文件信息追加输出到/home/bak.log
#!/bin/bash
date >> /home/bak.log
ls -l -F -R /home/tem >> /home/bak.log
第四、测试操作,字符串比较,逻辑操作
1、测试操作
#test 属性 文件名/路径名
或者#[ 属性 文件名/路径名 ](中括号与内部指令要有空格)
成功返回0,否则返回非0,该值不会显示在终端。可以使用#echo $?来查看上条命令的执行返回值。
属性有
-d:测试是否为目录
-e:目录或者文件是否存在
-f:是否为文件
-r:当前用户是否有权限读取
-w:当前用户是否有权限写入
-x:当前用户是否有权限执行
-L:是否为符号链接文件
例子:
#[ -d /home ]
该命令执行后通过#echo $?查看是0。
#[ -f /home]
该命令执行后通过#echo $?查看非0。
#test -d /home
该命令执行后通过#echo $?查看是0。
#test -f /home
该命令执行后通过#echo $?查看非0。
2、命令与操作
#[ -d /home ] && echo "YES"
因为[ -f file0 ]返回值为0即存在该文件,则可以执行后面的打印YES执行结果如下图:
因为这两条指令相与都会返回0,也就是说成功执行了指令,所以这条指令也是成功的返回0,通过#echo $?,可以看到。
#[ -f /home ] && echo "YES"
因为[ -f file0 ]返回值非0即不存在该文件,则后面的不执行,这好像是C语言中的与操作差不多。
每个命令的执行都会产生一个结果,返回0就正确,返回非0就代表执行指令失败。
3、整数值得比较
命令格式
[ num1 option num2 ] (中括号与内部指令要有空格)
Option:
-eq :等于
-ne :不等于
-gt : 大于
-lt :小于
-le :小于等于
-ge :大于等于
例如:
#[ 1 -eq 2 ] && echo “OK!”
通过#echo $? 可知是返回非零。不打印OK!。
#[ 2 -eq 2] && echo “OK!”
指令执行时成功的,并打印出OK!。
在当前终端执行
#who | wc -l
执行后立即会有返回值在终端上,如图
#[ ‘who | wc -l’ -eq 1] && echo “OK!”
单引号中可以使完整的指令,并且返回值为1,所以比较成功返回0。
#[ ‘who | wc -l’ -ne 1] && echo “OK!”
比较结果不成功。通过#echo $?可知出现返回值非零。
4、字符串的比较
命令格式1:
[ 字符串1 操作符 字符串2 ] (中括号与内部指令要有空格)
操作符:
== :等于
!= 不等于
命令格式2(字符串是否为空):
[ -z 字符串](中括号与内部指令要有空格)
例如
#[ “123” == “123” ] && echo “OK”
很显然比较成功,会返回OK
#[ “123” != “123” ] && echo “OK”
很显然比较失败,不会打印出OK
其他例子如下图:
在环境变量中有PWD这个变量,它就代表了当前的路径。
#[ -z “sssss” ]
通过#echo $? 可知返回非0
#[ -z “” ]
通过#echo $? 可知返回为0
5、逻辑比较
命令:
[ 操作1 ] 操作符 [ 操作2 ]
常用操作符:
-a或&&:逻辑与的关系,若第一个为假,则后面一个操作就不执行了。
-o或||:逻辑或的关系,若第一个为真,则后面的一个操作不执行。
!:逻辑否,指点的条件为真,则结果为假,条件为假,则结果为真。
第五、分支操作
1、单分支
格式:
if 条件测试命令
then 命令序列
fi
2、多分支格式
if 条件测试命令
then 命令序列
else 命令序列
if
3、if语句嵌套
if 条件测试命令1 ;then
命令序列1
elif 条件测试命令2 ; then
命令序列2
elif .....
else
命令序列n
fi
单分支例子:
if.sh文件中的内容
#!/bin/bash
LogFile="/home/file0"
if [ -f $LogFile ]
then echo "$LogFile is exist!"
fi
如果文件的内容是存在的,那么就会打印出“/home/file0 is exist!”的字符串。
多分支的例子:
if1.sh 的内容如下:
#!/bin/bash
echo "Check file exit!"
read -p "Please enter your file:" file_name
echo "**$file_name**"
if [ -f $file_name ]
then
echo "$file_name is exist!"
else
echo "$file_name is not exist!"
fi
执行情况
给出提示输入信息后,则输入文件名,并把数据的文件名打印出来,而后判断文件是否存在。
分支嵌套:
脚本如下:
提示输入信息,则输入文件名,在把文件名打印出来,第一分支检查该文件是否存在,第二个分支也是检查文件是否存在。打印相关信息。
执行结果图如下:
第六、循环语句
1、for循环
格式
for 变量名 in 取值序列
do
命令序列
Done
例子:
打印出三个字符串,文件内容如下图:
执行图如下:
字符串一次赋值
脚本如下:
运行结果如下:
2、while循环
格式:
while 命令或表达式
do
命令列表
done
例子:
输入一个数字,计算1到此数字的所有的整数的和。
脚本内容如下图:
执行脚本情况如下图:
第七、case
格式:
case 变量值 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
........
*)
默认执行的命令序列
esac
例子:
脚本文件的内容如下图:
执行情况如下图:
第八、until循环,在for、while、until中使用的continue, break
1、until
until 条件测试命令
do
命令序列
done
2、break和continue的用法和在C语言中的用法相同,含义也是相同的。
测试break的例子,输入若干个字符串到文件中,遇到END字符串结束输入,然后计算文件的行数,字节数。
脚本内容如下图:
输入三个字符串后,输入END,则终止输入字符串,显示文件的行数、字数、字节数。
continue测试用例,连续添加5个用户,stu1,stu2,stu3,stu4,stu5。然后删除stu1,stu3,stu5。保留stu2,stu4。
脚本内容如下图:
执行情况如下:
在执行后,创建了五个用户,然后保留下了stu2,stu4用户。
第八、shell函数
定义函数格式:
Function 函数名{
命令序列
}
或者
函数名(){
命令序列
}
调用已定义的函数
函数名
向函数内传递参数
函数名 参数1 参数2 ...
例1:
将上述的添加5个用户封装成一个函数
脚本内容如下:
#!/bin/bash
AddUser()
{
i=1
while [ $i -le 5 ]
do
adduser stu$i -D
#passwd --stdin stu$i < /home/psw.txt
i=$(($i + 1))
done
}
AddUser
AddUser
AddUser
i=1
while [ $i -le 5 ]
do
if [ $i -eq 2 ] || [ $i -eq 4 ]
then
[root@FORLINX6410]# vi fun.sh more
AddUser
AddUser
AddUser
i=1
while [ $i -le 5 ]
do
if [ $i -eq 2 ] || [ $i -eq 4 ]
then
let i++;
continue
fi
echo "i = $i"
deluser stu$i [16;17Hcontinue
i=$(($i + 1))
done
执行后结果如下图:
该脚本定义的函数执行了三次。所以添加用户添加了三次。
例2、从键盘上取出两个数,并计算他们的和
脚本内容如下:
脚本执行后如下图:
从键盘输了两个数分别为1和5,得到和为6
1、查看当前用户是否支持某条命令
#which [COMMAND...] 查看命令是否存在,如果存在会列出命令所在的位置。如果这条命令不存在,那么会列出所有的环境变量,告诉你在这么多目录中没有查找到该命令。
3、列出当前用户的环境变量
#echo $PATH
列出当前用户的所有的环境变量目录。
4、当前执行进程的名称
#echo $0
5、当前执行进程的PID
#echo $$
6、列出当前所在目录
#pwd
7、列出当前的用户名
echo $USER
8、上一条命令是否正常
#echo $?
返回0说明上一条命令正常,返回非零说明上一条命令错误
9、查看某个文件的内容
#tail -n 文件名
查看某个文件的最后n行。
10、列出目录下所有的文件以及子文件夹中的文件
#ls -l -F -R [路径]
不指定路径则为当前路径
11、添加用户
#adduser JCY1
成功后就会在/etc/passwd文件中会有一个JCY1用户信息表
12、删除用户
#deluser JCY1
成功后在/etc/passwd文件中没有了JCY1的用户信息表
13、更改JCY1用户的密码
#passwd JCY1 123456
14、列出所有的用户
#who
15、显示文件的行数,字数,字节数
wc命令的功能为统计指定文件中的字节数、字数、行数, 并将统计结果显示输出。
语法:wc [选项] 文件…
说明:该命令统计给定文件中的字节数、字数、行数。如果没有给出文件名,则从标准输入读取。wc同时也给出所有指定文件的总统计数。字是由空格字符区分开 的最大字符串。
该命令各选项含义如下:
- c 统计字节数。
- l 统计行数。
- w 统计字数。
这些选项可以组合使用。
输出列的顺序和数目不受选项的顺序和数目的影响。总是按下述顺序显示并且每项最多一列。
行数、字数、字节数、文件名
如果命令行中没有文件名,则输出中不出现文件名。
例如:
$ wc – lcw file1 file2
4 33 file1
7 52 file2
11 11 85 total
第三、标准输入输出向
2、标准输出重定向
cat命令用法
#cat test1.txt > test2.txt
test1.txt当中的内容把test2.txt覆盖掉,如果没有test2.txt会新建此文件,最终两个文件内容是一样的,并且是test1.txt的内容。
#cat test1.txt >> test2.txt
这种事追加写入,在test2.txt文件的后面继续添加test1.txt的全部内容
3、标准输入重定向
#passwd --stdin Jcy1 > /home/TestPwd.txt
从/home/TestPwd.txt文件的内容作为标准输入,如果/home/TestPwd.txt中的内容为6个字节“123456”。则给Jcy的用户设置密码为123456。
该命令就相当于#passwd Jcy1 123456
4、错误重定向
将中断出现的错误信息重定向其他的文件,假定当前目录下只有1.txt
#ls -l 1.txt 2.txt
该命令执行后会出现两种信息,一个真确的一个错误的。并且信息是在终端上显示。
#ls - 1.txt 2.txt >std.log 2>err.log
那么该目录下就会有两个文件了,std.log和err.log。那么错误信息就会在err.log中显示,正确信息就会在std.log中显示。
#ls - 1.txt 2.txt >std.log
正确信息写入了std.log,错误就会在终端显示。
若将上述的三条指令的>换成了>>,那么就会追加写入文件,否则在输出文件中只会显示最近一次的信息。
#ls -l 1.txt 2.txt &>err.log
终端会返回的无论正确的还是错误的都会显示在err.log文件中。
第四、shell脚本
2、脚本文件的内容包括
A、运行环境配置:#!/bin/bash独占首行,说明是使用bash来分析和执行脚本
B、注释信息:以#开头的说明性信息
C、可执行的linux命令。
2、执行脚本的方式
在执行脚本前要是脚本具有可执行的权限,使用#chmod 777 文件名
C、如果你在脚本文件所在目录,那么可以使用#./文件名
D、如果你在其他的目录下,那么可以使用#. 文件名完整路径
C、无论在那个路径下,可以使用#bash 文件名完整路径
D、无论在那个路径下,可以使用#sh 文件名完整路径
E、无论在那个路径下,可以使用#source 文件名完整路径
F、无论在那个路径下,可以使用#bash 文件名完整路径
4、例子测试
创建任务表需要使用crontab命令,对于该命令的用法请参考《linux创建计划任务表》这篇文章。在任务里面每隔2分钟就执行特定的脚本。任务表中添加如下任务:
*/2 * * * /home/bak.sh
bak.sh文件的内容如下:该内容是将/home/tem文件夹中文件信息追加输出到/home/bak.log
#!/bin/bash
date >> /home/bak.log
ls -l -F -R /home/tem >> /home/bak.log
第五、测试操作,字符串比较,逻辑操作
1、测试操作
#test 属性 文件名/路径名
或者#[ 属性 文件名/路径名 ](中括号与内部指令要有空格)
成功返回0,否则返回非0,该值不会显示在终端。可以使用#echo $?来查看上条命令的执行返回值。
属性有
-d:测试是否为目录
-e:目录或者文件是否存在
-f:是否为文件
-r:当前用户是否有权限读取
-w:当前用户是否有权限写入
-x:当前用户是否有权限执行
-L:是否为符号链接文件
例子:
#[ -d /home ]
该命令执行后通过#echo $?查看是0。
#[ -f /home]
该命令执行后通过#echo $?查看非0。
#test -d /home
该命令执行后通过#echo $?查看是0。
#test -f /home
该命令执行后通过#echo $?查看非0。
2、命令与操作
#[ -d /home ] && echo "YES"
因为[ -f file0 ]返回值为0即存在该文件,则可以执行后面的打印YES执行结果如下图:
因为这两条指令相与都会返回0,也就是说成功执行了指令,所以这条指令也是成功的返回0,通过#echo $?,可以看到。
#[ -f /home ] && echo "YES"
因为[ -f file0 ]返回值非0即不存在该文件,则后面的不执行,这好像是C语言中的与操作差不多。
每个命令的执行都会产生一个结果,返回0就正确,返回非0就代表执行指令失败。
3、整数值得比较
命令格式
[ num1 option num2 ] (中括号与内部指令要有空格)
Option:
-eq :等于
-ne :不等于
-gt : 大于
-lt :小于
-le :小于等于
-ge :大于等于
例如:
#[ 1 -eq 2 ] && echo “OK!”
通过#echo $? 可知是返回非零。不打印OK!。
#[ 2 -eq 2] && echo “OK!”
指令执行时成功的,并打印出OK!。
在当前终端执行
#who | wc -l
执行后立即会有返回值在终端上,如图
#[ ‘who | wc -l’ -eq 1] && echo “OK!”
单引号中可以使完整的指令,并且返回值为1,所以比较成功返回0。
#[ ‘who | wc -l’ -ne 1] && echo “OK!”
比较结果不成功。通过#echo $?可知出现返回值非零。
5、字符串的比较
命令格式1:
[ 字符串1 操作符 字符串2 ] (中括号与内部指令要有空格)
操作符:
== :等于
!= 不等于
命令格式2(字符串是否为空):
[ -z 字符串](中括号与内部指令要有空格)
例如
#[ “123” == “123” ] && echo “OK”
很显然比较成功,会返回OK
#[ “123” != “123” ] && echo “OK”
很显然比较失败,不会打印出OK
其他例子如下图:
在环境变量中有PWD这个变量,它就代表了当前的路径。
#[ -z “sssss” ]
通过#echo $? 可知返回非0
#[ -z “” ]
通过#echo $? 可知返回为0
6、逻辑比较
命令:
[ 操作1 ] 操作符 [ 操作2 ]
常用操作符:
-a或&&:逻辑与的关系,若第一个为假,则后面一个操作就不执行了。
-o或||:逻辑或的关系,若第一个为真,则后面的一个操作不执行。
!:逻辑否,指点的条件为真,则结果为假,条件为假,则结果为真。
第六、分支操作
2、单分支
格式:
if 条件测试命令
then 命令序列
fi
3、多分支格式
if 条件测试命令
then 命令序列
else 命令序列
if
4、if语句嵌套
if 条件测试命令1 ;then
命令序列1
elif 条件测试命令2 ; then
命令序列2
elif .....
else
命令序列n
fi
单分支例子:
if.sh文件中的内容
#!/bin/bash
LogFile="/home/file0"
if [ -f $LogFile ]
then echo "$LogFile is exist!"
fi
如果文件的内容是存在的,那么就会打印出“/home/file0 is exist!”的字符串。
多分支的例子:
if1.sh 的内容如下:
#!/bin/bash
echo "Check file exit!"
read -p "Please enter your file:" file_name
echo "**$file_name**"
if [ -f $file_name ]
then
echo "$file_name is exist!"
else
echo "$file_name is not exist!"
fi
执行情况
给出提示输入信息后,则输入文件名,并把数据的文件名打印出来,而后判断文件是否存在。
分支嵌套:
脚本如下:
提示输入信息,则输入文件名,在把文件名打印出来,第一分支检查该文件是否存在,第二个分支也是检查文件是否存在。打印相关信息。
执行结果图如下:
第七、循环语句
2、for循环
格式
for 变量名 in 取值序列
do
命令序列
Done
例子:
打印出三个字符串,文件内容如下图:
执行图如下:
字符串一次赋值
脚本如下:
运行结果如下:
3、while循环
格式:
while 命令或表达式
do
命令列表
done
例子:
输入一个数字,计算1到此数字的所有的整数的和。
脚本内容如下图:
执行脚本情况如下图:
第八、case
格式:
case 变量值 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
........
*)
默认执行的命令序列
esac
例子:
脚本文件的内容如下图:
执行情况如下图:
第八、until循环,在for、while、until中使用的continue, break
1、until
until 条件测试命令
do
命令序列
done
3、break和continue的用法和在C语言中的用法相同,含义也是相同的。
测试break的例子,输入若干个字符串到文件中,遇到END字符串结束输入,然后计算文件的行数,字节数。
脚本内容如下图:
输入三个字符串后,输入END,则终止输入字符串,显示文件的行数、字数、字节数。
continue测试用例,连续添加5个用户,stu1,stu2,stu3,stu4,stu5。然后删除stu1,stu3,stu5。保留stu2,stu4。
脚本内容如下图:
执行情况如下:
在执行后,创建了五个用户,然后保留下了stu2,stu4用户。
第八、shell函数
定义函数格式:
Function 函数名{
命令序列
}
或者
函数名(){
命令序列
}
调用已定义的函数
函数名
向函数内传递参数
函数名 参数1 参数2 ...
例1:
将上述的添加5个用户封装成一个函数
脚本内容如下:
#!/bin/bash
AddUser()
{
i=1
while [ $i -le 5 ]
do
adduser stu$i -D
#passwd --stdin stu$i < /home/psw.txt
i=$(($i + 1))
done
}
AddUser
AddUser
AddUser
i=1
while [ $i -le 5 ]
do
if [ $i -eq 2 ] || [ $i -eq 4 ]
then
[root@FORLINX6410]# vi fun.sh more
AddUser
AddUser
AddUser
i=1
while [ $i -le 5 ]
do
if [ $i -eq 2 ] || [ $i -eq 4 ]
then
let i++;
continue
fi
echo "i = $i"
deluser stu$i [16;17Hcontinue
i=$(($i + 1))
done
执行后结果如下图:
该脚本定义的函数执行了三次。所以添加用户添加了三次。
例2、从键盘上取出两个数,并计算他们的和
脚本内容如下:
脚本执行后如下图:
从键盘输了两个数分别为1和5,得到和为6