linux脚本命令
2.2.1.2、shell是一类编程语言
(1)编写shell脚本时使用的语言就是shell语言,又叫脚本语言。
(2)shell脚本其实是一类语言而不是一个语言。
2.2.1.3、常用shell语言:sh、bash、csh、ksh、perl、python等
(1)在linux下常用的脚本语言其实就是bash、sh;
(2)perl、python这样的高级shell脚本语言,常用在网络管理配置等领域,系统运维人员一般要学习这些。
(3)脚本语言一般在嵌入式中应用,主要是用来做配置。(一个复杂的嵌入式程序都是可配置的,配置过程就是用脚本语言来实现的)自然不会使用过于复杂的脚本语言特性,因此只需要针对性的学习即可。
(4)linux下最常用的脚本就是bash,我们学习也是以bash为主。
2.2.1.4、shell脚本的运行机制:解释运行
(1)C语言(C++)这种编写过程是:编写出源代码(源代码是不能直接运行的)然后编译链接形成可执行二进制程序,然后才能运行;而脚本程序不同,脚本程序编写好后源代码即可直接运行(没有编译链接过程)
(2)shell程序是解释运行的,所谓解释运行就是说当我们执行一个shell程序时,shell解析器会逐行的解释shell程序代码,然后一行一行的去运行。(顺序结构)
(3)CPU实际只认识二进制代码,根本不认识源代码。脚本程序源代码其实也不是二进制代码,CPU也不认识,也不能直接执行。只不过脚本程序的编译链接过程不是以脚本程序源代码为单位进行的,而是在脚本运行过程中逐行的解释执行时才去完成脚本程序源代码转成二进制的过程(不一定是编译链接,因为这行脚本程序可能早就编译连接好了,这里我们只是调用它)的。
(3)shell程序运行的运行有多种方法,这里介绍三种方法:
第一种:./xx.sh,和运行二进制可执行程序方法一样。这样运行shell要求shell程序必须具有可执行权限。chmod a+x xx.sh来添加可执行权限。
第二种:source xx.sh,source是linux的一个命令,这个命令就是用来执行脚本程序的。这样运行不需要脚本具有可执行权限。
第三种:bash xx.sh,bash是一个脚本程序解释器,本质上是一个可执行程序。这样执行相当于我们执行了bash程序,然后把xx.sh作为argv[1]传给他运行。
第四种:sh xx.sh
(1)shell程序的第一行一般都是: #!/bin/sh 这行话以#!开始,后面加上一个pathname,这行话的意思就是指定shell程序执行时被哪个解释器解释执行。所以我们这里写上/bin/sh意思就是这个shell将来被当前机器中/bin目录下的sh可执行程序执行。
可以将第一行写为:#!/bin/bash来指定使用bash执行该脚本。
注意:在ubuntu上面默认使用的解释器sh其实不是bash,而是dash。dash是ubuntu中默认使用的脚本解释器。
(2)脚本中的注释使用#,#开头的行是注释行。如果有多行需要注释,每行前面都要加#。(#就相当于是C语言中的//)
(3)shell程序的正文,由很多行shell语句构成。
命令参考网站
一.条件语句
if条件语句介绍Linux Shell之if条件判断语句
1.简单的变量数值判断
#!/bin/sh
# 两个变量判断是否相等
var1=1
var2=2
if [ "$var1" = "$var2" ]; then
echo '$var1 eq $var2'
else
echo '$var1 not eq $var2'
fi
2.文件和文件夹是否存在判断
加个!表示取反
#!/bin/sh
# 文件和文件夹是否存在判断
myPath="/var/log/httpd/"
myFile="/var/log/httpd/access.log"
# 这里的-x 参数判断$myPath是否存在并且是否具有可执行权限
if [ ! -x "$myPath"]; then
mkdir "$myPath"
fi
# 这里的-d 参数判断$myPath是否存在
if [ ! -d "$myPath"]; then
mkdir "$myPath"
fi
# 这里的-f参数判断$myFile是否存在
if [ ! -f "$myFile" ]; then
touch "$myFile"
fi
# 其他参数还有-n,-n是判断一个变量是否是否有值
if [ ! -n "$myVar" ]; then
echo "$myVar is empty"
exit 0
fi
3.判断程序是否存在并执行程序
如果条件一不成立就执行条件二,条件二不成立就结束
// eval $run执行改变量脚本
#!/bin/sh
PathFile1=/mypro/appRecord
PathFile2=/mypro/UpdateExe
if [ -f $PathFile1 ]; then
run="$PathFile1 &"// $run=/mypro/appRecord &”
eval $run
elif [ -f $PathFile2 ]; then
run="$PathFile2 &"// $run=/mypro/UpdateExe &”
eval $run
fi
二.脚本传入参数,$*
$0 这个程式的执行名字
$n 这个程式的第n个参数值,n=1..9
$* 这个程式的所有参数,此选项参数可超过9个。
$# 这个程式的参数个数
$$ 这个程式的PID(脚本运行的当前进程ID号)
$! 执行上一个背景指令的PID(后台运行的最后一个进程的进程ID号)
$? 执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误)
$- 显示shell使用的当前选项,与set命令功能相同
$@ 跟$*类似,但是可以当作数组用
三.根据进程名字关闭所有名字相关进程
1.获取PID并关闭进程
#带参数
<<!
pName=$1
echo $pName
pids=$(ps -ef | grep "$1" | grep -v grep | grep -v $0 | awk '{print $2}')
echo ----------------------
ps -ef | grep $pName | grep -v grep | awk '{print $1}' | xargs kill -9
!
#不带参数
#grep -v grep过滤grep,grep -v $0过滤脚本自己
pName=/mypro/appRecord
echo $pName
echo ------------------------------------------------------------------
# 根据进程名查询包含进程名的进程 并排除grep查询进程和此脚本进程
ps -ef | grep "$pName" | grep -v grep | grep -v $0
echo ------------------------------------------------------------------
# 打印进程名字和ID,pids是返回的进程ID列表,没有名字
pids=$(ps -ef | grep $pName | grep -v grep | grep -v $0 | awk '{print $1}')
echo $pids
# 根据结果停止所有名字相关进程
echo ----------------------
ps -ef | grep $pName | grep -v grep | awk '{print $1}' | xargs kill -9
简写,其实最后一条就够了
pName=/mypro/appRecord
echo $pName
ret=$(ps -ef | grep "$pName" | grep -v grep | grep -v $0)
echo "-->"$ret
ps -ef | grep $pName | grep -v grep | grep -v $0| awk '{print $1}' | xargs kill -9
// "|“后面的指令表示对”|"前面的结果出来如
ps -ef | grep $pName | grep -v grep | awk ‘{print $1}’ | xargs kill -9中
grep $pName是对ps -ef结果进行筛选
2.获取PID
简写,其实最后一条就够了
pName=/mypro/appRecord
echo $pName
ret=$(ps -ef | grep "$pName" | grep -v grep | grep -v $0 | awk '{print $1}')
echo $ret
三.注释
"<<!"开始多行注释 "!"结束多行注释
"#"单行注释
<<!
ls
ls /dev
!
# ls
四.exit退出脚本语句
#($ac_status=1退出 $ac_status=0不退出)
exit $ac_status
五.获取文本内容
test.txt文本内容
gkjgkjs
gsnjkgsdkjg
那我发
456461
rectxt=$(cat ./test.txt)
echo "rectxt-->$rectxt"
执行后输出
rectxt-->gkjgkjs
gsnjkgsdkjg
那我发
456461
六.grep指令使用
网络文件grep指令使用
1.Linux 里利用 grep 和 find 命令查找文件内容
递归查找文本所在的文件
当前目录下包括所有子文件下面的文件中查看保护字符串的文件
$ grep "被查找的字符串" -R ./*
从文件内容查找匹配指定字符串的行:
$ grep "被查找的字符串" 文件名
例子:在当前目录里第一级文件夹中寻找包含指定字符串的 .in 文件
grep "thermcontact" /.in
从文件内容查找与正则表达式匹配的行:
$ grep –e "正则表达式" 文件名
查找时不区分大小写:
$ grep –i "被查找的字符串" 文件名
查找匹配的行数:
$ grep -c "被查找的字符串" 文件名
从文件内容查找不匹配指定字符串的行:
$ grep –v "被查找的字符串" 文件名
从根目录开始查找所有扩展名为 .log 的文本文件,并找出包含 "ERROR" 的行:
$ find / -type f -name "*.log" | xargs grep "ERROR"
例子:从当前目录开始查找所有扩展名为 .in 的文本文件,并找出包含 "thermcontact" 的行:
find . -name "*.in" | xargs grep "thermcontact"
七.awk指令使用方法
awk是Unix环境下一种非常好的语言,适合于文本处理和报表生成,它还有许多精心设计的特性,允许进行特殊技巧程序设计。对于短消息来说,比如处理话单文件,使用awk就非常方便,鉴于测试组大部分人对awk并不熟悉,因此仅以本文作一个提纲挈领的介绍,希望对初学者迅速掌握awk有所帮助。
1、第一部分:入门,第一个awk程序
所有的编程书籍都是通过一个“Hello world!”简单程序入门,作为借鉴,本文也采用此方法带大家入门。现在,在当前目录下建立一个文本文件hello.txt,内容如下:
Hello world!
在命令行中输入以下命令
awk ‘{print}’ hello.txt
执行后hello.txt文件的内容显示在屏幕上。编写并且执行awk程序的方法很简单,如上所示,花括号内的是程序代码,后面的hello.txt为指定的输入文件。awk是一种行处理程序,执行awk时,它依次对输入文件中的每一行执行花括号中的代码,如上面的例子,就是对hello.txt中的每一行执行print命令。所有输出都发送到stdout,最后在屏幕上显示的结果为“Hello world!”。
2.2 常用变量
awk有自己的特殊变量集合。其中一些允许调整awk的运行方式,而其它变量可以被读取以收集关于输入的有用信息。下面列举出最基本的几个常用变量,并用例子一一说明用法.
$number表示记录的字段。比如,$1表示第1个字段,$2表示第2个字段,如此类推。而$0比较特殊,表示整个当前行
FS表示字段分隔符
NF表示当前记录中的字段数量
NR表示当前记录的编号(awk将第一个记录算作记录号1)
为了便于举例说明,在当前目录下生成一个历史话单文件test.txt,内容如下
gkjgkjs,45465
gsnjkgsdkjg,QQQ
那我,QSSSSSS,999999999
456461,YYYYYYYYYYYYY,UUUUUUUUUUUU
我们可以使用$0变量将整个test.txt文件内容读出:
可以看出,在awk中,print和print $0的作用完全一样。
awk '{ print $0 }' test.txt
#输出结果
gkjgkjs,45465
gsnjkgsdkjg,QQQ
那我,QSSSSSS,999999999
456461,YYYYYYYYYYYYY,UUUUUUUUUUUU
使用$number变量,对多个字段的文本进行处理,将变得非常容易,它可以让你毫不费力地引用每个独立的字段。
awk -F',' '{print $1}' test.txt
#输出结果
gkjgkjs
gsnjkgsdkjg
那我
456461
#-----------------------------------
awk -F',' '{print $2}' test.txt
#输出结果
45465
QQQ
QSSSSSS
YYYYYYYYYYYYY
#-----------------------------------
wk -F',' '{print $3}' test.txt
#输出结果
999999999
UUUUUUUUUUUU
上例中,在调用awk时,使用-F选项来指定","作为字段分隔符。而且,你还可以在字段中插入字符,比如:
awk -F',' '{print "ziduan1-->"$1,"ziduan2-->"$2}' test.txt
#输出结果
ziduan1-->gkjgkjs ziduan2-->45465
ziduan1-->gsnjkgsdkjg ziduan2-->QQQ
ziduan1-->那我 ziduan2-->QSSSSSS
ziduan1-->456461 ziduan2-->YYYYYYYYYYYYY
以上命令中,我们是通过-F选项来指定字段分隔符的。
八 .Linux xargs 命令
原文 xargs 命令
xargs(英文全拼: eXtended ARGuments)是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。
xargs 可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。
xargs 也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。
xargs 默认的命令是 echo,这意味着通过管道传递给 xargs 的输入将会包含换行和空白,不过通过 xargs 的处理,换行和空白将被空格取代。
xargs 是一个强有力的命令,它能够捕获一个命令的输出,然后传递给另外一个命令。
之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了 xargs 命令,例如:
find /sbin -perm +700 |ls -l #这个命令是错误的
find /sbin -perm +700 |xargs ls -l #这样才是正确的
九.读取ini配置文件
以配置文件test.txt为例(后缀名无所谓)
[comon]
ids=com1,com2,com3
files=profilefile
[oracle]
key="com1"
file="test1"
[mysql]
key="com2"
file="test2"
[sqlserver]
key="com3"
file="test3"
脚本代码,脚本文件名readini.sh
#!/bin/sh
function GetKey(){
section=$(echo $1 | cut -d '.' -f 1) #$1是函数传入的第一个参数
key=$(echo $1 | cut -d '.' -f 2)
sed -n "/\[$section\]/,/\[.*\]/{
/^\[.*\]/d
/^[ \t]*$/d
/^$/d
/^#.*$/d
s/^[ \t]*$key[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p
}" $__CONFIGFILE__
}
__CONFIGFILE__=$2 #$2 传入的文件名称
pass=$(GetKey $1) #$1 传入的需要读取的节和键,格式“节.键”
echo $pass
示例,使用格式:readini.sh 节.键 配置文件名字
./readini.sh oracle.key test.txt
#输出结果
"com1"
#-----------------------------------
./readini.sh mysql.file test.txt
#输出结果
"test2"
十.获取文件夹大小
1.获取已经使用的文件夹大小
详细说明:
du – 这是一个命令
-h – 以易读的格式显示大小 (例如 1K 234M 2G)
-s – 仅显示每个参数的总数
df – 命令可以查看挂载情况和空间使用情况
-h – 以易读的格式显示大小 (例如 1K 234M 2G)
获取data目录已经使用的大小
du -sh /data/ | awk '{print $1}'
#输出
336.3M
或者
df -h | grep /data | awk '{print $3}'
#输出
364.1M
有差异,不知道为什么
2.获取文件夹剩余大小
df -h | grep /data | awk '{print $4}'
#输出
5.3G
十一.判断网络是否正常
只能判断网络是否连接,不能判断是否可以解析域名
#define NETWORK_PATH "/sys/class/net/eth0/carrier" // 有线网络节点
/*******************************************************************
** 函数名: getNetworkStatus
** 函数描述: 获取当前的网络连接情况
** 参数: 无
** 返回: 返回0为断开连接,其他正常连接
********************************************************************/
int getNetworkStatus()
{
FILE *fp;
if ((fp = fopen(NETWORK_PATH, "r")) != NULL)
{
char ch = fgetc(fp);
fclose(fp);
return ch - '0';
}
return 0;
}
判断网线是否插入
检查网线是否插入可以查看
/sys/class/net/eth0/carrier 文件的内容。 1 表示网线有插入, 0 表示没接网线。
十二.判断是否有U盘挂载,获取挂载路劲
先用df -h命令查看挂载情况
~ $df -h
Filesystem Size Used Available Use% Mounted on
none 360.4M 0 360.4M 0% /dev
/dev/mmcblk0p7 635.4M 562.4M 59.9M 90% /
tmpfs 360.4M 0 360.4M 0% /dev/shm
tmpfs 490.0M 320.0K 489.7M 0% /tmp
tmpfs 490.0M 48.0K 489.9M 0% /run
none 360.4M 0 360.4M 0% /dev
/dev/mmcblk0p1 6.0G 493.6M 5.2G 8% /data
/dev/sda1 7.5G 333.1M 7.2G 4% /udisk/sda1
然后根据条件输出,只需要输出挂载点/dev/ 和挂载目录/udisk/满足的条件
~ $df -h | grep /dev/ | grep /udisk/ | awk '{print $6}'
/udisk/sda1
十三.打印当前行号
echo $LINENO
十四.shell函数定义
参考函数定义
实例
#!/bin/bash
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
输出结果:
-----函数开始执行-----
这是我的第一个 shell 函数!
-----函数执行完毕-----
十五. shell文件包含
Shell 文件包含
和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。
Shell 文件包含的语法格式如下:
. filename # 注意点号(.)和文件名中间有一空格
或
source filename
实例
创建两个 shell 脚本文件。
test1.sh 代码如下:
#!/bin/bash
url="http://www.editor.com"
test2.sh 代码如下:
#!/bin/bash
#使用 . 号来引用test1.sh 文件
. ./test1.sh
# 或者使用以下包含文件代码
# source ./test1.sh
echo "linux脚本命令:$url"
$ ./test2.sh
linux脚本命令:http://www.editor.com
十六.查找两个不同目录中同名的文件
将第一个目录列表存到a.txt,ls -1 ./usr/bin > a.txt
将第二个目录列表存到b.txt,ls -1 ./usr/bin > b.txt
然后 gerp -f a.txt b.txt
十七.查看运行的进程
ps -ef
十八.查看当前程序运行占用资源状况
top
查看程序的物理内存使用状况
找到进程号,如 12345
cat /proc/12345/status # VmRSS 对应的即为进程使用的物理内存
2729

被折叠的 条评论
为什么被折叠?



