shell的语法
准备工作
-
首先是必须在开头的时候写上解释器,例如
#!/bin/bash
,这样就指定好了我们的解释器 -
其次是注释,和python一样,shell也可以使用#作为注释
-
在shell中,你也可以写任何的shell命令,也就是像
cd,pwd,ls
等等
shell中的var
-
在shell中,已有的变量可以使用
$
符号来引用 -
也可以直接用等于号去赋值,例如
A=1
,然后我们就可以echo $A
,也就是输出A的值,但是需要注意的是,在赋值的时候,等于号两端不可以有空格,否则会发生赋值失败 -
然后就是一个
readonly
命令,这个命令可以这样使用,readonly a=3
,也就是说a在shell运行的时候一直是3,也不会被修改 -
unset
命令,这个命令可以撤销我们之前的赋值,unset a
,这样就会把我们之前赋值过的a取消 -
赋值字符串的时候有空格要加上引号
-
如果只是普通的创建变量,那么是不会被其他的shell程序所共享使用,比如我们上面把a赋值为3,那么假设我们有编写了一个shell程序
#!/bin/bash pwd echo $a
那么这个时候是不会输出
a=3
的,为了能使其他的shell程序也可以使用,那么我们需要使用一个关键字,就是export
关键字,例如export a
,这样就可以共享我们的变量 -
关于变量$0,$1,$2,这些参数都是可以输入的参数,例如下面的这个shell
#!/bin/bash echo "$0 $1 $2 $3"
这些变量的意思是,
$0
是我们的一个脚本的文件名,而$1
是我们的第一个参数,$2
是我们的第二个参数,这些参数都是可以输入的,假设这个shell程序叫做test.sh,那么我们在实行这个shell程序时bash test.sh
,那么如果不指定参数,就会输出test.sh
,假设指定参数(用空格分隔开来),例如bash test.sh hello world everyone
,那么就会输出test.sh hello world everyone
-
$#号
$#
这个变量用于检测你输入参数的个数,还是我们的那个test.sh,如果我在后面追加一行#!/bin/bash echo "$0 $1 $2 $3" #不用加上引号 echo $#
-
$* $@
这个两个是接受命令行参数的,不同的是$*是视为一个整体,而$@却是当作一个一个的参数,示例
#!/bin/bash echo "$0 $1 $2 $3" echo $# echo $* echo $@
-
$0
这个命令可以查看上一条bash命令是否正常执行了,如果执行成功,那么
echo $?
的结果就是0,否则就会是其他值 -
在Shell脚本中,
[]
是一个条件判断结构,用于进行各种条件测试。它和test
命令(可以写作[ expression ]
或者test expression
)功能相同,用于执行比较操作、文件测试以及其他类型的布尔逻辑测试。下面是一些基本的用法:
-
文件测试:
if [ -e file.txt ]; then echo "File exists." fi if [ -d /path/to/directory ]; then echo "Directory exists." fi if [ -f file.txt ]; then echo "It's a regular file." fi
-
字符串比较:
string="Hello" if [ "$string" = "Hello" ]; then echo "Strings are equal." fi
# 注意:字符串比较时需要使用双引号包裹变量名以避免解析错误
-
整数比较:
number=5 if [ $number -eq 5 ]; then echo "Number is equal to 5." fi
-
文件权限位测试:
if [ -r file.txt ]; then echo "File is readable." fi if [ -w file.txt ]; then echo "File is writable." fi if [ -x file.txt ]; then echo "File is executable." fi
-
复合条件:
if [ -f file1.txt ] && [ -s file1.txt ]; then echo "File1.txt exists and is not empty." fi if [ "$var1" != "" ] || [ "$var2" != "" ]; then echo "At least one of the variables is not empty." fi
-
特殊用法:
# 判断字符串长度是否为0 if [ -z "$empty_string" ]; then echo "String is empty." fi # 判断字符串长度是否不为0 if [ -n "$non_empty_string" ]; then echo "String is not empty." fi
注意,在
[]
内的表达式两边必须要有空格,例如[ $a -eq $b ]
中的$a
、-eq
和$b
之间都应有空格。同时,如果条件表达式包含特殊字符或空格,建议总是将变量用双引号包围起来,如["$a"]
,以防止解析错误。另外,bash还提供了一个增强版的条件判断结构
[[ ... ]]
,它具有更丰富的特性,比如支持正则表达式匹配,并且内部的某些操作不需要额外的转义字符。例如:if [[ $variable =~ pattern ]]; then echo "Variable matches the regex pattern." fi
-
分支与循环
-
其实这里的if...else...与python很像,首先是
if [ ];then command1 elif [ ];then command2 else command3 fi
写出来的shell程序应该满足这样的要求,所以有我们的第一个shell程序
#!/bin/bash if [ $1 -eq 1 ];then echo "hhh" elif [ $1 -eq 2 ];then echo "cls" else echo "No such thing" fi
-
case语句
这里可以输入一个参数,比如我们输入第一个参数
#!/bin/bash case $1 in 1) command1 #双分号结尾,代表着break,加上分号以满足语法 ;; 2) command2 ;; 3) command3 ;; #*就是匹配所有的情况吧 *) command4 ;; #最后结尾必须加上esac
下面是一个示例的shell程序
#!/bin/bash case $1 in 1) echo "I am yxw" ;; 2) echo "I am zxp" ;; 3) echo "I am sleeping" ;; *) echo "Else" ;; esac
-
for循环
-
示例,计算1+2+3...+100
#!/bin/bash sum=0 for((i=1;i<=100;i++));do sum=$((sum+i)) done echo "$sum"
可以写成这样的,也可以
#!/bin/bash sum=0 #换行不加分号 for((i=1;i<=100;i++)) do sum=$((sum+i)) done echo "$sum"
-
打印所有输入的参数
#!/bin/bash for i in $* do echo "$i" done
-
while循环
#!/bin/bash i=0 sum=0 #需要注意的是,下面那个i前面是带有$符号 # [ ]这个语法是条件判断,注意括号两边一定有空格 while [ $i -le 100 ] do sum=$((sum+i)) ((i++)) done echo $sum
-
read函数
案例实操 read命令,-t可以选择等待时间,-p可以选择提示信息 其实展示的这个案例挺奇怪的 这个意思是在控制台等待7s,在等待期间,如果超过7秒,进程会被杀死,在7秒内输入NAME,就会在控制台打印出来
#!/bin/bash read -t 7 -p "Enter your name" NAME echo $NAME
-
basename
这个命令可以除去路径信息,只保留文件名称 例如,在/home/shellcmd/路径下有一个test.txt文件,这时,如果我们只想得到文件名称,就可以这样
basename /home/shellcmd/test.txt
这样就会输出 test.txt 如果我们不想把文件的后缀名也输出出来,只输出test的话 可以这样,在命令后面加上.txt后缀
basename /home/shellcmd/test.txt .txt
-
dirname
与上面的相似,可以类比记忆,这个命令是删除文件名,保留路径
dirname /home/shellcmd/test.txt
这样就会输出/home/shellcmd/
函数
-
函数的格式
function_name() { # 函数体内的命令或语句 command1 command2 ... } # 或者使用更简洁的语法 function function_name { # 函数体内的命令或语句 command1 command2 ... } # 甚至可以省略 'function' 关键字(推荐) function_name () { # 函数体内的命令或语句 command1 command2 ... }
例如,我们可以写一个计算输入参数的函数
sum
function sum(){ echo $(($1+$2)) }
这个符号
$(())
,就是计算表达式,之前的符号$1,$2
就是我们输入的第一个,第二个参数,写完这个函数后,还需要再调用一次,可以把这个sum.sh
表示出来#!/bin/bash function sum(){ echo $(($1+$2)) } sum $1 $2
这样就可以在终端里面进行计算
bash sum.sh 1 2
输出结果是
3
系统工具
-
cut指令
cut 指令,字面上就是切的指令,首先这个有两个比较有用的参数,一个是-d,另一个是-f -d是指定切割的标志,默认是以'\t'为空格,-f是以列为参数
可以演示一下,比如在一个名为cut.txt的文件内有如此几行
shang hai wang wen xiang wen ha ha ha zhu tou
我们想要把第一列切割出来,如下
shang wang xiang ha zhu
那么我们就可以使用cut命令
cut -d " " -f 1 cut.txt #这个命令的意思是以空格为分割符,-f是切割出来第一列,切割cut.txt
第二个案例是在cut.txt文件中切出来wang这个字符,这就需要一些关于shell的小知识了,首先,我们可以使用
cat
命令来查看我们这个文件的标准输出cat cut.txt
然后就是我们的
grep
命令,我们可以使用grep去过滤wanggrep wang
其次就是使用我们的
cut
命令,那么我们可以利用管道符|
把前两个的标准输出连接起来,当作第三个命令的标准输入cat cut.txt | grep wang | cut -d " " -f 1
这样就可以切割出来
-