变量的定义:
1.=左右不要有空格
2.如果内容有空格,需要使用单引号括起来
3.双引号支持转义 $开头的变量会
a=1
b=severiruby
d="hello from testerhome"
e='hello from "大家伙"'
f=`ls`
变量的使用:
echo:是向屏幕输出
echo $a
单引号:括起来的内容包括$x,都会被当成字符串
双引号:括起来的内容中的$x,会被引用
反引号:反引号里面的内容会被当成一个命令去执行
a=`ls`
echo $a 输出:输入当前目录的显示的文件
array=(`ls`) 将当前目录下的文件赋值一个变量
echo ${array[@]} 输出:当前目录下的所有显示的文件
;(分号)表示一行命令的结束即放在多行执行
例如:
a=123
echo 'this is $a' 输出是:this is $a
echo "this is $a" 输出是:this is 123
打印没有定义的变量:
例如:a=123
echo ${a}_1 输出:123_1
预定义变量:
echo $PWD:打印当前目录的路径
echo $UESR:打印的用户
echo $HOME:打印当前的家目录
echo $PATH:打印当前的环境变量
which:只会在当前的环境变量里面去查找
数组:一个连续的内存段,或者可以理解为一个集合
数组的定义:用小括号括起来,用空格分隔开
array=(1 2 3 4 5)
echo ${array[@]} 取出所有的值,@加上双引号还是被当做数组来处理
echo ${array[*]} 取出所有的值,*加上双引号会被当成字符串来处理
echo ${array[2]} 取出下标为2的值
特殊字符:
1.反斜杠: 转义字符
2.$(()),对变量进行操作,例如加减乘除
a=1;b=3
echo $((a+b))
3.$(ls) 表示ls执行后的结果,与``反引号类似,不过可以嵌套
4.``反引号,代表命令的输出
5.(()) 是整数扩展,把里面的变量当做整数去处理
a=1;b=2
(($a>$b));echo $? 输出结果为:1 1>2结果是错误的,所以显示1
(($a<$b));echo $? 输出结果为:0 1<2结果是正确的,所以显示0
$?:表示上个语句的执行结果
在bash里面0代正确,1代表错误的
array=(`seq 1 10`) 创建1到10的数组
数字变量操作:
a=1
echo $(($a+1))或者
((a+=1))
echo $a
字符串操作:
s='hello from testerhome'
echo ${s:6:3}
第一个参数存储的字符串的变量
第二个参数是从第几项开始,包括这一项
第三个参数是从第几项结束,包括这一项
${#s}:计算字符串的长度
去掉头部:
echo ${s#hello}:删除字符串开头的“hello”,默认去掉后面空格
echo "${s#hello}":加上双引号不会去掉后面的空格
echo ${s#*o}:删除“o”以前的字符(包括本身),非贪婪匹配,值匹配到第一个
echo ${s##*m}:贪婪匹配,删除字符串中所以有m之前的字符串(包括m本身)
去掉尾部:
echo ${s%h*}:从后面是删除,已"h"开头的后面的字符(包括其本身),非贪婪匹配
echo ${s%%o*}:贪婪匹配,删除所有已"o"开头的后面的字符(包括其本身)
替换:
echo ${s/testerhome/severiruby} :用severiuby替换testerhome
echo ${s/h/xxx}:将字符串中第一个h字符替换成xxx,非贪婪替换
echo ${s//h/xxx}:
布尔变量:
true
false
❖ 命令执⾏返回值 $?
❖ 任何命令执⾏都会有⼀个返回值
❖ 0表⽰正确
❖ ⾮0表⽰错误
算数判断:
[ 2 –eq 2 ] 相等
❖ [ 2 –ne 2 ] 不等
❖ [ 3 –gt 1 ] 大于
❖ [ 3 –ge 3 ] 大于等于
❖ [ 3 –lt 4 ] 小于
❖ [ 3 –le 3 ] 小于等于
❖ (())也可以表⽰算术⽐较。((10>=8)) ,((10==10))
字符串比较:
a="test";b="hello test"
[ $a = $b ] :如果两个字符串相等,则结果为真
[ $a != $b ] : 如果两个字符串不相同,则结果为真
[ -n "$a" ] : 如果字符串不是空,则结果为真
[ -z "$a" ] : 如果字符串是空,则结果为真
逻辑判断:
-a:与--只有一个为假,则结果为假
-o:或--只要一个为真,则结果为真
[ 2 -ge 1 -a 3 -ge 4 ];echo $? 表示:1大于等于1与3大于等于4,求“与”,结果为:假
[ 2 -ge 1 -o 3 -ge 4 ];echo $? 表示:1大于等于1与3大于等于4,求“或”,结果为:真
[[ 2 -ge 1 && 3 -ge 4 ]];echo $? 与
[[ 2 -ge 1 || 3 -ge 4 ]];echo $? 或
[ ! 2 -ge 1] 非 表示2不大于等于1,结果为假
if 条件判断;
then
为真时执行的语句;
else
为假时执行的语句;
fi
if [ -e 1.txt ];then echo exist;else echo not exist;fi 如果1.txt是文件,那么输出exist;否则,输出not exist
简写:
ls 1.txt && echo exist || echo not exist 如果1.txt存在,输出exist;否则输出not exist
[ -e test ] || echo exist && echo not exist
||:表示当判断为false的时候执行
&&:表示当判断为true的时候执行
for 语法:
for ((i=0;i<10;i++));
do
满足条件是执行的语句
done
不满足条件是执行
for循环:
例子:
数组:用小括号括起来
array=(a b c d e)
for ((i=0;i<${#array[*]};i++));do echo ${array[i]};done
for遍历循环:
例子:
array=(a b c d e)
for x in ${array[*]};do echo $x;done
遍历目录下的所有文件:
for x in *;do echo $x;done
while循环:
i=0;
while ((i<3));do
echo $i;
((i=i+1));
done
while read line;do echo $line;done < 2
循环读取文件2中字符
read:读入一个标准输入
read -p "enter:" x;echo 我刚刚输入了:$x
-p:想当于input
退出循环:
break:直接跳出循环
for x in *;do echo $x;if [ -d $x ];then break;fi;done
continue:跳出本次循环,进入下次循环
for x in *;do echo $x;if [ -f $x ];then $x is file;else continue;fi;done
$$:获取当前的进程号
(a=1;echo $a):小括号表示的子shell
{a=1;echo $a}:大括号表示当前的语句块
&;放在后台执行进程
$!:获取后台的最后一个进程的进程号
jobs:显示后台运行的进程
fg:将从后台进程放到前台执行
vim文件中的操作:
set number 设置行号
set nonu 取消行号
gg 跳转到文件头部 (在esc模式下)
GG 跳转到文件尾部 (在esc模式下)
在文件中复制:
在esc模式下,按住v,按上下左右进行选中要复制的内容,然后在按v,再按p进行复制
>:表示将内容输出到某个文件,并且第二次输出,会覆盖上一次的内容
>>:不会覆盖上一次的内容
echo "hello testerhome" > 1.txt
<:将某个文件中内容输入
read x < 1.txt
将错误信息输入到某个文件:
ls ddd > a 2>&1:将错误信息写入到a,2>&1是固定的
Shell 输入与输出
echo ,printf可以简单输出变量。
> file 将输出重定向到另⼀个⽂件
>> 表示追加 等价于tee -a
< file 输⼊重定向
| 表示管道,也就是前一个命令的输出传一个命令的输入
echo "* ????":放入到引号中可以避免转义
Shell环境变量
set 可以获得当前的所有变量,declare
unset 可以释放变量
env 可以获得可以传递给⼦进程的变量
export aa=bbbb 把私有变量导出,等价于declare -x
Linux三剑客
grep:基于正则表达式查找满足条件的行,即数据查找定位
awk:根据定位到的数据行处理其中的分段, 即数据切片
sed :根据定位到的数据行修改数据, 即数据修改
grep:
grep -i pattern file 忽略大小写
grep -v pattern file 不显示匹配的行
grep -o pattern file 精准匹配
grep -E pattern file 使用扩展正则表达式
grep pattern -r dir/ 递归搜索
-A -B -C 后面都跟阿拉伯数字
-A是显示匹配后和它后面的n行。
-B是显示匹配行和它前面的n行。
-C是匹配行和它前后各n行。
总体来说,-C覆盖面最大。用它保险些。这3个开关都是关于匹配行的上下文的(context)。
于是:grep -A 4 wikipedia 密码文件.txt
就是搜索密码文件,找到匹配“wikipedia”字串的行,显示该行后后面紧跟的4行。
awk:
awk 'BEGIN{}END{}' 开始和结束
awk '/running/' 正则匹配
awk '/aa/,/bb/' 区间选择
awk '$2~/xxx/' 字段匹配
awk 'NR==2' 去第二行
awk 'NR>1' 去掉第一行
awk内置变量:
FS:字段分隔符
OFS:输出数据的字段分隔符
RS:记录分隔符即行分隔符
ORS:输出字段的行分隔符
NF:字段数
NR: 记录数即行数
awk的字段处理:
-F 参数指定字段分隔符
BEGIN{FS="-"} 也可以表示字段分隔符
$0代表当前的记录
$1代表第一个字段
$2代表第N个字段
$NF代表最后一个字段
一键搭建网站:
python2 -m CGIHTTPServer 8000
python3 -m http.server -cgi 8000
脚本:
#:表示注释
$0:表示执行的程序,是相对于执行目录的路径
$1,$2,$3分别表示第几个参数,默认shell只支持9个参数
$@,$*表示所有的参数,不包含$0
${#*}和${#@}:表示参数的个数
$@于$*的区别:
$@:可以在函数直接传递参数,并不改变参数的排列
$*:会把参数打散,相对顺序不变,但是参数的个数就变了
函数:Function f(){...}
Function可以省略,除了可以在脚本文件中使用函数外,换可以在shell中定义,这些定义会在本次shell结束后消失
如果没有return,返回值是最后一句指令的返回值
执行方式:
chmod u+x xxx.sh ./xxx.sh
bash xxx.sh
source xxx.sh
bash -x :读取每一句,并执行,可以方便的看到执行的语句
set -x:在当前shell中调试,set+x还原
统计指定的进程的CPU100次:
for i in {1..100};do top -d 1 -n 1 -p 2167 | grep 2167 | awk '{print $10}';done
从PATH中,已冒号为记录行,修改每行最后一个
cat $PATH | awk 'BEGIN{RS=":"}{print $0}' | sed 's#/[^/]*$#jjjjj#g'
从shell服务器上的/tmp/nginx.log中找出所有404和500的报错数据,并去除其中的url
grep -E " 404|500 " /tmp/nginx.log
awk '$9~/404|500/{print}' nginx.log | sed 's# /[0-9a-z]*##g';
获取访问量最高的ip:
awk '{print $1}' /tmp/nginx.log | sort | uniq -c | sort -n | tail -10
Shell中的>/dev/null 2>&1 与 2>&1 >/dev/null 与&>/dev/null 的区别
>/dev/null 2>&1
// 实际上,应该等同于这样: 1>/dev/null 2>/dev/null ,默认情况下就是1,标准输出,所以一般都省略。 而&符号,后面接的是必须的文件描述符。不能写成2>1,这样就成了标准错误重定向到文件名为1的文件中了,而不是重定向标准错误到标准输出中。所以这里就是:标准输出重定向到了/dev/null,而标准错误又重定向到了标准输出,所以就成了标准输出和标准错误都重定向到了/dev/null
2>&1 >/dev/null
// 咋一看,这个跟上面那个有啥区别呢,不也是标准错误重定向到标准输出,而标准输出重定向到/dev/null么? 最后不应该都重定向/dev/null么? 我是这么理解的!一条指令同一时刻要么产生标准错误,要么产生标准输出。 当产出标准错误的时候,因这个标准错误重定向到了标准输出,而标准输出是输出到屏幕。这个时候标准输出还没有被重定向到/dev/null,于是在屏幕上打印了。当产生标准输出时,那么它就不是标准错误,2>&1无效,于是标准输出重定向dev/null,不打印到屏幕。所以最终结果将是:标准错误打印到屏幕,而标准输出不打印到屏幕。
&>/dev/null
// 这个就是,不管你是啥玩意儿文件描述符,通通重定向到/dev/null
shell curl 取得HTTP返回的状态码
curl -I -m 10 -o /dev/null -s -w %{http_code} www.baidu.com
- -I 仅测试HTTP头
- -m 10 最多查询10s
- -o /dev/null 屏蔽原有输出信息
- -s silent 模式,不输出任何东西
- -w %{http_code} 控制额外输出