1. 相关命令
1.1 source
- 读取脚本文件,执行文件里的代码
source first_shell.sh
1.2 shell中调python
#!/usr/bin/bash
ls
python <<-EOF
print("hello world")
EOF
1.3 查看一个命令的位置
which ls
1.4 命令的历史记忆功能
- history 查看历史命令
- !number 执行编号为number的历史命令
- !string 找到最近一个以string开头的历史命令执行
- !$ 找到上一个命令的最后一个参数 (然后执行)
- !! 找到上一个命令并执行
1.5 一些快捷键
- Ctrl+D :退出
- Ctrl+R :模糊搜索一个历史命令
- Ctrl+A :光标移动到行首
- Ctrl+E :光标移动到行尾
- Ctrl+U :删除行首到光标处的字符
- Ctrl+K : 删除光标到行尾处的字符
- Ctrl+Y : 撤销
- Ctrl+C : 终止程序运行
1.6 前后台运行程序
- Ctrl+C : 将当前程序挂起,暂时不运行
- bg : 将挂起的程序后台运行
- fg : 将挂起的程序或者后台运行的程序 放到前台运行
1.7 重定向
- 0 : 标准输入
- 1 :标准输出
- 2 :标准错误
- > : 输出重定向
- < : 输入重定向
- >> :: 输出重定向,追加方式
- &> : 混合重定向,表示将标准输出,标准错误都重定向指定位置
1.8 命令排序
- 分号 分号分割的命令会依次执行,无论前面是否出现错误
date;date;
- && 前一个命令成功后才会执行下一个命令
./configure && make && make install
- || 前一个命令执行不成功才会执行下一条命令
ls /home/222/333 || mkdir -p /home/222/333
# 逻辑判断
ping -c1 www.baidu.com && echo "ping success" || echo "ping fail"
1.9 & 含义
- command & : 命令最后加一个&,表示后台执行
- command &> /dev/null : 混合重定向,/dev/null 是一个特殊的文件
- command1 && command2 : 命令排序,逻辑判断
1.10 元字符 (跟正则还是有区别的)
- * : 任意多个字符
- ? : 任意一个字符
- [] : 匹配括号中的任意一个字符 [abc] [0-9] [^a-Z] ^表示取反
- () : 表示在子shell中执行
#!/bin/bash
data=10
(
# 子shell完成,不会影响当前shell的值
data=100
echo "()里面的data= $data"
)
echo "当前data=$data"
- {} : 表示在当前shell中执行
#!/bin/bash
data=10
{
# 当前shell完成,会影响当前shell的值
data=100
echo "{}里面的data= $data"
}
echo "当前data=$data"
- {} : 在匹配时表示集合
# 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt
touch {1..9}.txt
# 笛卡尔积a1.txt a2.txt a3.txt b1.txt b2.txt b3.txt c1.txt c2.txt c3.txt
touch {a..c}{1..3}.txt
# hello. hello.img hello.txt
touch hello.{,txt,img}
- \ : 转义符
1.11 shell的三种执行方式
- . a.sh : 以当前shell解析器来执行脚本
- source a.sh : 也是以当前shell解析器来执行脚本
- ./a.sh : 以文件中#!指定的解析器来执行脚本
- bash a.sh : 以指定的bash解析器来执行脚本
- -vx : 以调试的方式运行
1.12 字符串中的变量
- " " : 双引号中的变量会被解析
num=100
echo "$num"
- ' ' : 单引号中的内容个会原样输出
num=100
echo '$num'
- ` ` : 字符串中的反引号中的内容会被当作系统命令执行,并用其执行结果替换,等价于$()
# 当然,需要跟双引号搭配使用,单引号表示原样输出,不会解析
echo "today is `date`"
- -e : 如果想识别字符串中的转义字符,需要加参数-e
echo -e "##\n##"
1.13 输入之 read
read -t 180 -p '请输入选择 :' choose
- -p 提示语句
- -t 指定时间,单位为秒
- -s 输入密码时,不会显
1.14 整数运算
- 方式一: expr
# 必须要有空格
expr 1 + 3
sum=`expr $num1 + $num2`
# 乘法
sum=`expr $num1 \* $num2`
- 方式二: $(())
# 必须要双括号
echo $((1+3))
num1=1
num2=2
echo $((num1/num2))
echo $(($num1+$num2))
- 方式三:$[]
echo $[5+2]
echo $[2**10]
num=$[2**10]
echo $[num2**num1]
- 方式四: let
let 1+2
let num=1+2
let i++
1.15 变量内容的删除和替换
- 删除
url=www.sina.com.cn
# 统计字符串长度
echo ${#url}
# 输出字符串
echo ${url}
# 从前往后,最短匹配
echo ${url#*.}
# 从前往后,最长匹配,贪婪匹配
echo ${url##*.}
# 从后往前,最短匹配
echo ${url%.*}
# 从后往前,最长匹配,贪婪匹配
echo ${url%%.*}
1.16 字符串切片
url=www.baidu.com
echo ${url:0.5}
echo ${url:0:10}
echo ${url:5} # 下标从5到结束
1.17 字符串替换
url=www.baidu.com
echo ${url/baidu/sina}
1.18 变量的替代
# 输出var,若不存在变量var,则新建并设置其值为aaa
echo ${var-aaa}
# 输出var,若var不存在或者为空值,用aaa替代
echo ${var:-aaa}
2. 变量
2.1 临时的自定义变量
- 定义变量 : 变量名=变量值
name=zhangsan
# 有空格需要加""
A="hello world"
#交互式定义变量
read -p "请输入姓名:" name
# -s:不显示用户输入的内容
read -p "请输入你的密码:" -s password
- 引用变量 : $变量名 或 ${变量名}
- unset 清除变量
num=100
echo $num
unset num
echo $num
#!/bin/bash
read -p "请输入ip: " ip
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ]; then
echo "$ip is up."
else
echo "$ip is down"
fi
2.2 环境变量
- 环境变量在当前shell和子shell中生效
# 当前shell窗口有效
export name=zhangsan
# 环境变量的多个值用冒号分割
export PATH=/usr/local/mysql/bin:$PATH
2.3 全局变量
- $HOME/.bashrc :当前用户有效
- $HOME/.bash_profile :当前用户有效
- /etc/bashrc :所有用户生效
- /etc/profile :所有用户和系统都生效
以上文件的修改需要重启或者source指令才能生效
读取顺序
- /etc/profile // 打开shell会执行该脚本文件
- $HOME/.bash_profile // 打开时执行
- $HOME/.bahsrc // 打开时执行
- /etc/bashrc // 打开时执行
- $HOME/.bash_logout // 退出shell会执行该脚本文件
- 以 su - user1 切换账户会执行以下脚本文件
- /etc/profile
- $HOME/.bash_profile
- $HOME/.bahsrc
- /etc/bashrc
- 以 su user1 切换账户会执行以下脚本文件
- $HOME/.bahsrc
- /etc/bashrc
2.4 系统变量
- $0 当前脚本的名称
- $n 当前脚本的第n个参数 n<=9
- ${n} 当前脚本的第n个参数,n>9
- $# 当前脚本的参数个数(不包括程序本身);
- $* 当前脚本的所有参数(不包括程序本身);以字符串方式
- $@ 当前脚本的所有参数(不包括程序本身);以数组方式
- $? 脚本或程序执行完后的状态,返回0表示执行成功
- $! 上一个后台进程的pid
- $$ 程序本身的PID号。
# $?: 上一条指令返回的状态:0标识执行正常,非0标识执行异常
echo "\$? = $?"
# $0 当前执行的程序或脚本名
echo "\$0=$0"
# $#: 当前脚本后面接的参数个数
echo "\$# = $#"
# $@ : 脚本后面的所有参数,以数组形式
echo "\$@ = $@"
# $*: 脚本后面的所有参数,以字符串形式
echo "\$* = $*"
# 对于脚本后面前9个参数的获取方式
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
# 脚本后面第9个参数以后的参数获取方式
echo "\$11 = ${11}"
echo "\$12 = ${12}"
2.5 数组定义
# 定义数组方式1
array[0]=v1
array[1]=v2
array[2]=v3
array[3]=v4
# 定义数组方式2 以空格分割
array=(var1 var2 var3 var4)
#读取数组指定下标元素
echo ${array[0]}
2.5 其他变量相关操作
A=/root/Desktop/shell/mem.txt
# 取出目录
dirname $A
# 取出文件名
basename $A
3. sed
3.1 添加数据(按行添加)
# 第二行后面追加hello world。然后在控制台显示出来
sed '2a hello world' a.txt
# 直接修改源文件
sed -i '2a hello world' a.txt
# 指定行前面插入hello world
sed '3i hello world' a.txt
# 直接修改源文件
sed -i '3i hello world' a.txt
# 在含有hello的行前面插入hello world 。用来正则表达式
sed '/hello/ i hello world' a.txt
# 在含有hello的行后面插入hello world
sed '/hello/ a hello world' a.txt
# 最后一行后面添加hello
sed '$a hello' a.txt
# 最后一行前面添加hello
sed '$i hello' a.txt
3.2 删除行
# 删除第一行数据
sed '1d' a.txt
# 直接修改源文件
sed -i '1d' a.txt
# 删除含有hello的行
sed '/hello/d' a.txt
# 删除匹配行到最后一行
sed '/hello/,$d' a.txt
3.3 修改指定行
# 将第一行修改为hello
sed '1c hello' a.txt
# 将最后一行修改为hello
sed '$c hello' a.txt
# 将含有hello的行修改为hi
sed '/hello/ c hi' a.txt
3.4 替换
# 按行查找,替换每一行第一个hello为hi
sed 's/hello/hi/' a.txt
# 按行查找,替换所有的hello为hi
sed 's/hello/hi/g' a.txt
3.5 执行多个命令
sed -e '1d' -e '2d' a.txt