echo hello
echo -e "a\tb"
hello.sh
#!/bin/bash
echo hello
//通过Bash调用执行脚本
sh hello.sh
//赋予执行权限,直接运行
chmod 755 hello.sh
chmod u+x hello.sh
./hello.sh
alias cp="cp -i"vi ~/.bashrcunalias 别名$PATH环境变量定义的目录查找顺序找到的第一个命令| 命令 | 含义 |
|---|---|
| ctrl+c | 强制终止当前命令 |
| ctrl+l | 清屏 |
| ctrl+a | 光标移动到命令行首 |
| ctrl+e | 光标移动到命令行尾 |
| ctrl+u | 从光标所在的位置删除到行首 |
HISSIZE=10000!n 重复执行第n条历史命令!! 重复执行上一条命令!字符 重复执行最后一条以该字符串开头的命令history -c
1 echo 1
2 echo 2
3 echo 3
!2
!!
!echo
| 设备 | 设备文件名 | 文件描述符 | 类型 |
|---|---|---|---|
| 键盘 | /dev/stdin | 0 | 标准输入 |
| 显示器 | /dev/stdout | 1 | 标准输出 |
| 显示器 | /dev/stderr | 2 | 标准错误输出 |
| 类型 | 符号 | 作用 |
|---|---|---|
| 标准输出重定向 | 命令 > 文件 | 以覆盖的方式,把命令的正确输出输出到指定的文件或设备当中 |
| 标准输出重定向 | 命令 >> 文件 | 以追加的方式,把命令的正确输出输出到指定的文件或设备当中 |
| 错误输出重定向 | 命令>文件 | 以覆盖的方式,把命令的错误输出输出到指定的文件或设备当中 |
| 错误输出重定向 | 命令>>文件 | 以追加的方式,把命令的错误输出输出到指定的文件或设备当中 |
| 正确输出和错误输出同时保存 | 命令>文件 2>&1 | 以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中 |
| 正确输出和错误输出同时保存 | 命令>文件 2>>&1 | 以追加的方式,把正确输出和错误输出都保存到同一个文件当中 |
| 正确输出和错误输出同时保存 | 命令&>文件 | 以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中 |
| 正确输出和错误输出同时保存 | 命令&>>文件 | 以追加的方式,把正确输出和错误输出都保存到同一个文件当中 |
| 正确输出和错误输出同时保存 | 命令>>文件1 2>文件2 | 以覆盖的方式,正确的输出追加到文件1中,把错误输出追加到文件2中 |
wc命令的功能为统计指定文件中的行数、字数、字节数, 并将统计结果显示输出< 文件把文件做为命令的输入wc < a.txt
| 多命令执行符 | 格式 | 作用 | 案例 |
|---|---|---|---|
| ; | 命令1;命令2 | 多个命令执行,命令之间没有任何逻辑联系 | echo 1;echo 2; |
| && | 命令1&&命令2 | 逻辑与 当命令1正确执行,则命令2才会执行 当命令1执行不正确,则命令2不会执行 | echo 1&&echo 2; |
| \\ | 命令1\\ 命令2 | 逻辑或 当命令1执行不正确,则命令2才会执行 当命令1正确执行,则命令2不会执行 | echo 1\\echo 2; |
echo 1;echo 2;
echo 1&&echo 2;
echo 1||echo 2;
ls /etc/ | more
netstat -an | grep ESTABLISHED | wc -l
| 通配符 | 作用 |
|---|---|
| ? | 匹配一个任意字符 |
| * | 匹配0个或任意字符,也就是可以匹配任意内容 |
| [] | 匹配中括号中任意一个字符 |
| [-] | 匹配中括号中任意一个字符,-代表范围 |
| [^] | 匹配不是中括号中的一个字符 |
| 符号 | 作用 |
|---|---|
| '' | 单引号。在单引号中所有的特殊符号,如$和`都没有特殊含义 |
| "" | 双引号,在双引号里特殊符号都没有特殊含义,但是 $ ` \ 例外,拥有调用变量值,引用命令和转义的含义 |
|
反引号,扩起来的是系统命令 |
| $() | 和反引号一样 |
| # | 在shell脚本中,#开头的行代表注释 |
| $ | 用于调用变量的值 |
| \ | 转义符号 |
echo '$PATH'
echo "$PATH"
echo `ls`
echo $(ls)
echo -e "a\tb"
name="zhufeng"
age=10
echo $变量名
$ x=1
$ y=2
$ z=3
$ k=$x+$y+$z
$ echo $k
1+2+3
m="$x"2
n=${x}2
echo $m $n
set | grep zhufeng
unset a
export 变量名=变量值
export envName=prod
env | grep envName
| 变量名 | 含义 | 示例 |
|---|---|---|
| HOSTNAME | 主机名 | HOSTNAME=localhost |
| SHELL | 当前的shell | SHELL=/bin/bash |
| HISTSIZE | 历史命令条数 | HISTSIZE=1000 |
| SSH_CLIENT | 当前操作环境如果是用SSH连接的话,这里会记录客户端IP | SSH_CLIENT=192.168.1.100 57596 22 |
| USER | 当前登录的用户 | USER=root |
echo $HOSTNAME
echo $SHELL
echo $HISTSIZE
echo $SSH_CLIENT
echo $USER
# echo $PATH
/usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
如果想把一个自定义的脚本直接可以执行,或者把这个文件拷贝到目标目录下,或者把脚本所在目录添加到环境变量中的PATH路径中
/root/shells/hello.sh
#!/bin/bash
echo hello
export PATH="$PATH":/root/shells
hello.sh
locale来设置程序运行的不同语言环境,locale由ANSI C提供支持。locale的命名规则为<语言>_<地区>.<字符集编码>,如zh_CN.UTF-8,zh代表中文,CN代表大陆地区,UTF-8表示字符集。locale
LANG=zh_CN.UTF-8
echo $LANG
| 位置参数变量 | 作用 |
|---|---|
| $n | n为数字,$0代表命令本身,$1-$9代表第1到第9个参数,10以上的参数需要用大括号包含,如${10} |
| $* | 这个变量代表命令中所有的参数,$*把所有的变看数看成一个整体 |
| $@ | 这个变量也代表命令行中所有的参数,不过$@把每个参数进行区分 |
| $# | 这个变量代表命令行中所有参数的个数 |
sum.sh
#!/bin/bash
num1=$1
num2=$2
sum=$((num1+num2))
echo $sum
sh sum.sh 3 4
vi for.sh
#!/bin/bash
for i in "$@"
do
echo "i=$i"
done
sh for.sh 1 2 3
i=1
i=2
i=3
vi for2.sh
#!/bin/bash
for i in "$#"
do
echo "i=$i"
done
sh for2.sh 1 2 3
i=1 2 3
vi for3.sh
#!/bin/bash
echo "$#"
sh for3.sh 1 2 3
3
| 位置参数变量 | 作用 |
|---|---|
| $? | 最后一次执行的命令的返回状态。0表示正确执行,非0表示不正确执行 |
| $$ | 当前进程的进程号(PID) |
echo $?
echo $$
read [选项] [变量名]
| 选项 | 含义 |
|---|---|
| -p | 提示信息,在等待read输入时,输出提示信息 |
| -t | 秒数: read命令会一直等待用户输入,使用此选项可以指定等待时间 |
| -n | 字符数,read命令只接受指定的字符数,就会执行 |
| -s | 隐藏输入的数据,适用于机密信息的输入 |
#!/bin/bash
read -p 'please input your name:' -t 5 name
echo -e "\n"
read -p 'please input you gender[m/f]:' -n 1 gender
echo -e "\n"
read -p 'please input your password:' -s password
echo -e "\n"
echo $name,$gender,$password
sh read.sh
| 选项 | 含义 |
|---|---|
| - | 给变量设定类型属性 |
| + | 取消变量的类型属性 |
| -a | 将变量声明为数组类型 |
| -i | 将变量声明为整数型 |
| -x | 将变量声明为环境变量 |
| -r | 将变量声明为只读变量 |
| -p | 显示指定变量的被声明的类型 |
a=1
b=2
c=$a+$b
echo $c
1+2
declare -i c=$a+$b //声明成整型
echo $c
3
declare +i c //取消变量的类型属性
c=$a+$b
echo $c
1+2
declare -i c="3" //给变量设定类型属性
declare -p c //显示指定变量的被声明的类型
//declare -i c="3"
//声明环境变量
declare -x kk=1
set | grep kk //查看所有变量
env | grep kk //只查看系统变量
declare -r x //只读
x=2 //bash: x: readonly variable
//声明为数组类型
declare -a names;
names[0]=zhangsan
names[1]=lisi
//默认只打印第一个元素
echo ${names}
zhangsan
//打印第2个元素
echo ${names[1]}
lisi
//打印全部
echo ${names[*]}
zhangsan lisi
declare -x命令declare -p 可以查看所有的类型export NAME=zhufeng
declare -x NAME=zhufeng
declare -r gender=m
gender=f
-bash: gender: readonly variable
declare -p 查询所有变量的属性declare -p 变量名 查询指定变量的属性num1=2
num2=3
sum=$(expr $num1 + $num2)
echo $sum
5
sum2=$(($num1+$num2))
echo $sum2
5
sum3=$[$num1+$num2]
echo $sum3
5
d=$(date)
echo $d

result=$(((1+2)*4/2))
echo $result
6
. 配置文件PATH等此文件登录时起作用的环境变量| 路径 | 说明 |
|---|---|
| /etc/profile | |
| /etc/bashrc | |
| ~/.bash_profile | 只会对当前用户生效 |
| ~/.bashrc | 只会对当前用户生效 |

cat /etc/profile | grep USER
| 变量名 | 含义 |
|---|---|
| USER | 用户名 |
| LOGNAME | 登录名 |
| 邮箱地址 | |
| PATH | 查找路径 |
| HOSTNAME | 主机名 |
| umask | 权限掩码 |
| /etc/profile.d/星.sh |
PATH路径/etc/bashrcPS1 登录提示符在这里修改umaskPATH变量/etc/profile.d/星.sh文件~/.bash_logout~/.bash_history/etc/issue/etc/issue.net/etc/motd| 参数 | 含义 |
|---|---|
| \d | 当前系统日期 |
| \s | 显示操作系统名称 |
| \l | 显示登录的终端号 |
| \m | 显示硬件体系结构,如i386等 |
| \n | 显示主机名 |
| \o | 显示域名 |
| \r | 显示内核版本 |
| \t | 显示当前系统时间 |
| \u | 显示当前登录用户的序列号 |
vi /etc/ssh/sshd_config
Banner /etc/issue.net
service sshd restart
| 符号 | 含义 |
|---|---|
| ? | 匹配任意一个字符 |
| * | 匹配任意多个字符 |
| [] | 匹配中括号中范围内的一个字符 |
alias grep='grep --color=auto'
| 元字符 | 作用 | 示例 |
|---|---|---|
| * | 前一个字符匹配 0 次或任意多次 | grep 1* reg.txt |
| . | 匹配除换行符外的任意一个字符 | grep . reg.txt |
| ^ | 匹配行首。例如,^hello 会匹配以 hello 开头的行 | grep ^a reg.txt |
| $ | 匹配行尾。例如,hello& 会匹配以 hello 结尾的行 | grep a$ reg.txt |
| [] | 匹配屮柄号屮指定的任意一个字符,而且只匹配一个字符。 例如.[aoeiu]匹配任意一个元音字母, [0-9] 匹配任意一位数字, [a-z][0-9] 匹配由小写字母和一位数字构成的两位字符 |
grep ab[bc]c reg.txt |
| [^] | 匹配除中括号中的字符以外的任意一个字符。例如,[^0-9] 匹配任意一位非数字字符, [^a-z] 匹配任意一位非小写字母 |
grep a[^fg]c reg.txt |
| \ | 转义符,用于取消特殊符号的含义 | grep \.$ reg.txt |
| {n} | 表示其前面的字符恰好出现 n 次。例如,[0-9]{4} 匹配4位数字,[1][3-8][0-9]{9} 匹配手机号码 | grep "a{1}" reg.txt |
| (n,} | 表示其前面的字符出现不少于 n 次。例如,[0-9]{2,} 匹配两位及以上的数字 | grep "a{1,}" reg.txt |
| {n,m} | 表示其前面的字符至少出现 n 次,最多出现 m 次。例如,[a-z]{6,8} 匹配 6〜8 位的小写字母 | grep "a{2,3}" reg.txt |
提取用户名和它使用的shell
cat /etc/passwd | cut -f 1,7 -d :
| 参数 | 含义 |
|---|---|
| %ns | 输出字符串,n是数字指代输出几个字符 |
| %ni | 输出整数,n是指输出几个数字 |
| %m.nf | 输出浮点数,m和n是数字,指代输出的整数位数和小数位数,如%6.2f代表输出6位位,2位小数,4位整数 |
printf "%s\t%s\t%s\t%s\t%s\t\%s\n" $(df -h | grep /dev/vda1) | cut -f 1,5
动作(Action)
$0 整行 $1 第一列...
df -h | grep /dev/vda1 |awk '{print $5}'| cut -d '%' -f 1
echo "" > numbers.txt
awk 'BEGIN{print "开始"}END{print "结束"}' numbers.txt
awk 'BEGIN{FS=":"}{print $1"\t"$2}' /etc/passwd
numbers.txt
1
2
3
awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}' numbers.txt
6
score.txt
zhangsan 91
li 81
wangwu 71
awk '$2>90{print $1"\t优秀"}$2>80{print $2"\t良好"}' score.txt
awk '{print NR,$0}' score.txt
echo "i love you" | awk 'BEGIN{ FS=" ";OFS="-" }{print $1,$2,$3}'
vi操作| 参数 | 含义 | 示例 |
|---|---|---|
| a | 追加,在每一行或者指定行下面添加一行或多行 | sed '1a newline' score.txt |
| c | 行替换,用c后面的字符串替换掉原始整个数据行 | sed 'c newline' score.txt |
| s | 字符串替换,用一个字符串替换另外一个字符串,格式为 "行范围s/旧字符串/新字符串/g" | sed '3s/lisi/lisisi/g' score.txt |
| i | 插入,在当前行插入一行或多行 | sed '1i newline' score.txt |
| d | 删除指定的行 | sed '1,2d' score.txt |
| p | 打印,输出指定的行 | sed -n '2p' score.txt |
| 参数 | 含义 | 示例 |
|---|---|---|
| -n | 一般sed命令会把所有的数据都输出到屏幕上,如果加入此选项则只会把处理过的行输出到屏幕上 | sed -n '2p' score.txt |
| -e | 允许对输入数据应用多条sed编辑命令 | sed -e 's/91/92/g;s/81/82/g' score.txt |
| -i | 用sed的修改直接修改编辑的文件,而不是在屏幕上输出 | sed -i '1i newline' score.txt |
| 选项 | 含义 | |
|---|---|---|
| -f | 忽略大小写 | sort -f -t ":" -n -k 5,5 /etc/passwd |
| -n | 以数值型进行排序,默认使用字符串顺序 | sort -t ":" -n -k 3,3 /etc/passwd |
| -r | 反向排序,默认从小到大 | sort -r /etc/passwd |
| -t | 指定分割符,默认分割符是制表符 | sort -t ":" -k 3,3 /etc/passwd |
| -k n[,m] | 按照指定的字段范围排序。从第n个字段开始,到第m个字段结束,默认是到行尾 | sort -t ":" -k 3,3 /etc/passwd |
sort /etc/passwd
sort -r /etc/passwd
sort -t ":" -k 3,3 /etc/passwd
| 选项 | 含义 |
|---|---|
| -l | 只统计行数 |
| -w | 只允许单词数 |
| -m | 只统计字符数 |
wc wc.txt
| 选项 | 含义 |
|---|---|
| -d | 文件是否存在并且是目录 |
| -e | 文件是否存在 |
| -f | 文件是否存在并且是普通文件 |
| -b | 文件是否存在并且是块设备文件 |
| -c | 文件是否存在并且是字符设备文件 |
| -L | 文件是否存在并且是链接文件 |
| -p | 文件是否存在并且是管道文件 |
| -s | 文件是否存在并且是否为非空 |
| -S | 文件是否存在并且是套接字文件 |
touch 1.txt
test -e 1.txt
[-e 1.txt]
echo $?
exist.sh
[ -e 1.txt ]&&echo "yes"|| echo "no"
yes
[ -e 11.txt ]&&echo "yes"|| echo "no"
no
| 选项 | 含义 |
|---|---|
| -r | 文件是否存在,并且是否拥有读权限 |
| -w | 文件是否存在,并且是否拥有写权限 |
| -x | 文件是否存在,并且是否拥有执行权限 |
echo read > read.txt
echo write > write.txt
echo execute > execute.txt
chmod u+w write.txt
chmod u+x execute.txt
[ -r read.txt ]&&echo "read yes"|| echo "no"
[ -w write.txt ]&&echo "write yes"|| echo "no"
[ -x execute.txt ]&&echo "execute yes"|| echo "no"
| 选项 | 含义 |
|---|---|
| 文件1 -nt 文件2 | 判断文件1的修改时间是否比文件2的新 |
| 文件1 -ot 文件2 | 判断文件1的修改时间是否比文件2的旧 |
| 文件1 -ef 文件2 | 判断文件1和文件2的inode号是否一致,可用于判断硬链接 |
[ write.txt -nt read.txt ]&&echo "write is older than read"|| echo "no"
[ read.txt -ot write.txt ]&&echo "read is older than write"|| echo "no"
ln execute.txt execute2.txt
[ execute.txt -ef execute2.txt ]&&echo "execute and execute2.txt are the same"|| echo "no"
| 选项 | 含义 |
|---|---|
| 整数1 -eq 整数2 | 判断整数1是否和整数2相等 |
| 整数1 -ne 整数2 | 判断整数1是否和整数2不相等 |
| 整数1 -gt 整数2 | 判断整数1是否大于整数2 |
| 整数1 -lt 整数2 | 判断整数1是否小于整数2 |
| 整数1 -ge 整数2 | 判断整数1是否大于等于整数2 |
| 整数1 -le 整数2 | 判断整数1是否小于等于整数2 |
[ 2 -eq 2 ]&&echo "2==2"|| echo "no"
[ 3 -ne 2 ]&&echo "2!=2"|| echo "no"
[ 3 -gt 2 ]&&echo "2>2"|| echo "no"
[ 1 -lt 2 ]&&echo "2<2"|| echo "no"
[ 2 -ge 2 ]&&echo "2>=2"|| echo "no"
[ 2 -le 2 ]&&echo "2<=2"|| echo "no"
| 选项 | 含义 |
|---|---|
| -z 字符串 | 判断字否串是否为空 |
| -n 字符中 | 判断字符串是否为非空 |
| 字符串1 == 字符串2 | 判断字符串1是否和字符串2相等 |
| 字符串1 != 字符串2 | 判断字符串1是否和字符串2不相等 |
name=zhufeng
[ -z "$name" ]&&echo "空"|| echo "非空"
[ -n "$name" ]&&echo "非空"|| echo "空"
name2=zhufeng
[ "$name" == "$name2" ]&&echo "相等"|| echo "不相等"
[ "$name" != "$name2" ]&&echo "不相等"|| echo "相等"
| 选项 | 含义 |
|---|---|
| 判断1 -a 判断2 | 逻辑与 |
| 判断1 -o 判断2 | 逻辑或 |
| !判断 | 逻辑非 |
[ 2 -gt 1 -a 3 -gt 2 ]&&echo "yes"|| echo "no"
[ 2 -gt 1 -a 3 -gt 4 ]&&echo "yes"|| echo "no"
[ 2 -gt 1 -o 3 -gt 4 ]&&echo "yes"|| echo "no"
[ ! 3 -gt 4 ]&&echo "yes"|| echo "no"
fi结尾test命令进行判断,所以中括号和条件判断式之间必须有空格if [条件判断];then
代码体
fi
if [条件判断]
then
代码体
fi
if [ 2 -gt 1 ];then echo bigger; fi
if [ 2 -gt 1 ]
then
echo bigger
fi
isRoot.sh
#!/bin/bash
user=$(whoami)
user=`whoami`
if [ "$user" == root ]
then
echo "我是root用户"
fi
if [条件判断]
then
代码体1
else
代码体2
fi
isDir.sh
#!/bin/bash
read -t 10 -p "请输入一个路径" dir
if [ -d "$dir" ]
then
echo "$dir是目录"
else
echo "$dir不是目录"
fi
if [条件判断1]
then
代码体1
elif [条件判断2]
代码体2
else
代码体3
fi
grade.sh
#!/bin/bash
read -p "请输入一个分数" grade
if [ "$grade" -gt 90 ]
then
echo 优秀
elif [ "$grade" -gt 80 ]
then
echo 良
else
echo 差
fi
case 变量名 in
值1)
代码块1
;;
值2)
代码块2
;;
*)
代码块3
;;
esac
case.sh
#!/bin/bash
read -p "yes or no?" -t 30 choose
case $choose in
"yes")
echo '是'
;;
"no")
echo "否"
;;
*)
echo 其它
;;
esac
for 变量 in 值1 值2 值3
do
代码块
done
for.sh
#!/bin/bash
for i in 1 2 3
do
echo $i
done
#!/bin/bash
for((i=1;i<=10;i++));
do
echo $(($i));
done
while [条件判断式]
do
代码块
done
while.sh
#!/bin/bash
i=1
result=0
while [ $i -le 100 ]
do
result=$(($result+i))
i=$(($i+1))
done
echo $result
until.sh
#!/bin/bash
i=1
result=0
until [ $i -gt 100 ]
do
result=$(($result+i))
i=$(($i+1))
done
echo $result
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用function fun() 定义,也可以直接fun() 定义,不带任何参数()[ function ] funcName [()]
{
action;
[return int;]
}
start(){
> echo start
> }
start
#!/bin/bash
start(){
echo start
}
start
sum(){
> result=$(($1+$2))
> return $result
> }
sum4 2 3
echo $?
5
| 参数处理 | 说明 |
|---|---|
| $# | 传递到脚本的参数个数 |
| $* | 以一个单字符串显示所有向脚本传递的参数 |
| $@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数 |
| $$ | 脚本运行的当前进程ID号 |
| $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误 |
set -e 遇到执行非0时退出脚本, set -x 打印执行过程ip.sh
#!/bin/bash
for IP in $@; do
if ping -c 1 $IP &>/dev/null; then
echo "$IP is ok."
else
echo "$IP is wrong!"
fi
done
sh ip.sh 127.0.0.1