shell语法:
shell是我们通过命令行与操作系统沟通的语言
shell脚本可以直接在命令行中执行,也可以将一套逻辑组织成一个文件,方便复用
bash版本:(linux常用版本)
.sh文件开头加上:
#! /bin/bash 指明bash为脚本解释器
echo 输出->cout/printf
运行方式:
解释器执行
(1)bash+文件名test.sh
可执行文件执行
(2)chmod +x test.sh 增加可执行权限 r读w写x可执行
ls-l test.sh(查看权限)
./test.sh
/home/acs/test.sh
~/test.sh
注释:
#单行注释--跟py一样
:<<EOF
注释1
注释2
EOF
EOF可以换成其他字母,还有个别字符,如:!
定义变量:
name1="tkw"
name2='tkw'
name3=tkw
输出变量
name=yxc
echo $name # 输出yxc
echo ${name} # 输出yxc
echo ${name}acwing # 输出yxcacwing
加括号主要是为了明确边界
将变量变成只读变量
readonly name
declare -r name
删变量
unset name
删完一个变量如果不存在就是空字符串
自定义变量(局部变量)
子进程不能访问的变量
环境变量(全局变量)
子进程可以访问的变量
局部变量改为全局变量
export name
declare -x name
bash命令新开一个bash
exit退出当前bash
新建一个全局变量
export name=yxc
declare +x name
全局变回局部
获取字符串长度 echo ${#name}
获取从0开始的5个字符 echo ${name:0:5}
echo $0 ->文件名
echo $1 ->第一个参数
...
echo ${10} ->第十个参数
echo $# ->输出参数个数
不常用:
$* 由所有参数构成的用空格隔开的字符串,如上例中值为"$1 $2 $3 $4"
$@ 每个参数分别用双引号括起来的字符串,如上例中值为"$1" "$2" "$3" "$4"
$$ 脚本当前运行的进程ID
重要
$? 上一条命令的退出状态(注意不是stdout,而是exit code)。0表示正常退出,其他值表示错误
(类似return 0)
$(command) 返回command这条命令的stdout(可嵌套)
如:$(ls)
`command` 返回command这条命令的stdout(不可嵌套)
数组:
可以直接用小括号定义
array=(1 abc "def" yxc)
array[0]=1
array[1]=abc
array[2]="def"
array[3]=yxc
${变量}
$(stdout标准输出里面的命令)
echo ${array[@]} 输出所有(中间没用的空间会留下来)
echo ${#array[*]} 输出使用了的数组长度
expr不是bash里面的命令
用空格隔开
用专义字符转义\
expr的返回值都是stdout结果
test返回结果返回到了exit code里面(退出状态)
expr length "$str"
expr index "$str" aWd (aWd中任意一个字符在str字符串中出第一个出现的位置,下标从1开始)
expr substr "$str" 2 3
a=3
b=4
echo `expr $a + $b` # 输出7
echo `expr $a - $b` # 输出-1
echo `expr $a \* $b` # 输出12,*需要转义
echo `expr $a / $b` # 输出0,整除
echo `expr $a % $b` # 输出3
echo `expr \( $a + 1 \) \* \( $b + 1 \)` # 输出20,值为(a + 1) * (b + 1)
()需要转义
a|b(返回第一个不为0的值)
a不是0,会直接返回第一个值,短路原则
a是0,会返回第二个值,如果第二个值是空串,会返回0
a&b
有0返回0,没0返回a
= 和 == 一样
a=3
b=4
echo `expr $a \> $b` # 输出0,>需要转义
echo `expr $a '<' $b` # 输出1,也可以将特殊字符用引号引起来
echo `expr $a '>=' $b` # 输出0
echo `expr $a \<\= $b` # 输出1
c=0
d=5
echo `expr $c \& $d` # 输出0
echo `expr $a \& $b` # 输出3
echo `expr $c \| $d` # 输出5
echo `expr $a \| $b` # 输出3
echo `expr $a + 3 + 4`
a = expr
read命令(相当于c++的cin)
read name
read -p "what's your name" name1
read -p "what's your name" -t 5 name1 (-t 5 等待5秒)
echo命令
man echo看echo的用法
echo "hello ac terminal"
想输出转义字符,得用双引号或者不加引号
单引号不行
echo -e 'hello\nworld'
打开转义
echo -e "acwing \c"
echo tkw
这样就没有自动换行了
(单双引号都行,但没引号不行)
默认输出到终端里面,也可以输出到文件里面(重定向到文件)
echo "hello world" > output.txt
原样输出.不进行转义或者取变量(用单引号)
echo '$name\"'
显示命令的执行结果(``会将命令的标准输出截取 <==> $() )
echo `date`
echo ${date}
printf
printf "%10d.\n" 123 # 占10位,右对齐
printf "%-10.2f.\n" 123.123321 # 占10位,保留2位小数,左对齐
printf "My name is %s\n" "yxc" # 格式化输出字符串
printf "%d * %d = %d\n" 2 3 `expr 2 \* 3` # 表达式的值作为参数
test命令:
shell内置
判断一个表达式是否为真
[]和test几乎用法一模一样
&&
两者有一个假就不做了,返回假
为真(0)就执行下一个
||
两者有一个真就不做了,返回真
为假(非0)就执行下一个
exit code返回结果(return) 0表示真,非0表示假 (0表示正常结束)
expr stdout返回结果 1表示真 0表示假
test 2 -lt(小于) 3
echo $?(获取上一个语句的退出状态)
expr1 && expr2:当expr1为假时,直接忽略expr2
expr1 || expr2:当expr1为真时,直接忽略expr2
test -e test.sh && echo "exist" || echo "Not exist"
exist # test.sh 文件存在
test -e test2.sh && echo "exist" || echo "Not exist"
Not exist # testh2.sh 文件不存在
test -e filename # 判断文件是否存在
-f 判断是不是文件
-d 判断是不是目录(文件夹)
test -r filename # 判断文件是否可读
-w 是否可写
-x 是否可执行
-s 是否为空
数值比较
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-gt 是否大于
-le 是否小于等于
-ge 是否大于等于
字符串比较
-z判断字符串是不是空,空则true
-n判断字符串是不是非空,非空则true
== 判断两个字符串是否相等
!= 判断两个字符串是否不等
test 和 [] 互换
判断语句
if condition
then
语句1
语句2
...
fi
如果为逻辑关系表达式,
expr同时会在exit code中输出结果,如果结果为真,exit code为0,否则为1
如果为其他运算表达式 exit code为0
多重判断语句
if condition
then
语句1
语句2
...
elif condition
then
语句1
语句2
...
elif condition
then
语句1
语句2
else
语句1
语句2
...
fi
a=4
if [ $a -eq 1 ]
then
echo ${a}等于1
elif [ $a -eq 2 ]
then
echo ${a}等于2
elif [ $a -eq 3 ]
then
echo ${a}等于3
else
echo 其他
fi
for循环语句
for i in a 2 cc
do
echo $i
done
for file in `ls`
do
echo $file
done
seq 1 10
会返回1~10
for i in $(seq 1 10)
do
echo $i
done
for i in $(seq 1 10)
do
echo $i
done
for ((i=1; i<=10; i++))
do
echo $i
done
while read name
do
echo $name
done
read命令当读到文件结束符(ctrl+d)时返回1,否则返回0(正常退出)
与while相反,条件为假则做do里面的,为真则退出
until condition
do
语句1
语句2
...
done
当用户输入yes或者YES时结束,否则一直等待读入。
until [ "${word}" == "yes" ] || [ "${word}" == "YES" ]
do
read -p "Please input yes/YES to stop this program: " word
done
break跳出这层for循环
;;跳出case
continue和c++完全一样,跳出当前这次循环
while read name
do
for ((i=1;i<=10;i++))
do
case $i in
8)
break
;;
*)
echo $i
;;
esac
done
done
每次输入一个name,然后输出1~7
for ((i=1;i<=10;i++))
do
if [ `expr $i % 2` -eq 0 ]
then
continue
fi
echo $i
done
每次将%2为0的跳过,即输出1~10所有奇数
ps aux返回当前打开的所有进程
top 查看当前运行的所有进程
shift+f按照内存排序
找到pid,退出
kill -9 pid
exit命令:
#! /bin/bash
if [ $# -ne 1 ] # 如果传入参数个数等于1,则正常退出;否则非正常退出。
then
echo "arguments not valid"
exit 1
else
echo "arguments valid"
exit 0
fi
$0返回的是文件名
stdin 标准输入,向命令行读取数据,文件描述符为0
stdout 标准输出,向命令行输出数据,文件描述符为1
stderr 标准错误输出,向命令行输出数据,文件描述符为2