Shell脚本常见问题

mkdir rmdir rm

  1. mkdir 创建文件夹
mkdir -p filename

-p 确保目录名称存在,不存在的就建一个。

mkdir -p runoob2/test

若 runoob2 目录原本不存在,则建立一个。(注:本例若不加 -p 参数,且原本 runoob2 目录不存在,则产生错误。)
2. rmdir 删除文件夹

rmdir [-p] filename

于目前目录有适当权限的所有使用者
filename:删除空的目录。
参数: -p 是当子目录被删除后使它也成为空目录的话,则顺便一并删除。

rmdir -p BBB/Test 
#箬过删除Test后BBB是空白文件夹,则把BBB文件夹也删除
  1. rm
rm [options] filename

option参数:
-i 删除前逐一询问确认。
-f 即使原档案属性设为唯读,亦直接删除,无需逐一确认。
-r 将目录及以下之档案亦逐一删除。

if [ -z $1] ;then

if [ -z $1] ;then
echo "Hello";exit
fi

-z : 在if中是 空 的意思。
$1: 表示第一个参数

if [ $# -ne 1 ];then

$# 是启动脚本时携带的参数个数
-ne 是不等于
这个语句的意思是“如果shell的启动参数不等于1个”
$# 表示提供到shell脚本或者函数的参数总数;
$1 表示第一个参数。

-ne 表示 不等于

另外:
整数比较
-eq 等于,如:if [“ a " − e q " a" -eq " a"eq"b” ]
-ne 不等于,如:if [“ a " − n e " a" -ne " a"ne"b” ]
-gt 大于,如:if [“ a " − g t " a" -gt " a"gt"b” ]
-ge 大于等于,如:if [“ a " − g e " a" -ge " a"ge"b” ]
-lt 小于,如:if [“ a " − l t " a" -lt " a"lt"b” ]
-le 小于等于,如:if [“ a " − l e " a" -le " a"le"b” ]
< 小于(需要双括号),如:((“ a " < " a" < " a"<"b”))
<= 小于等于(需要双括号),如:((“ a " < = " a" <= " a"<="b”))
> 大于(需要双括号),如:((“ a " > " a" > " a">"b”))
>= 大于等于(需要双括号),如:((“ a " > = " a" >= " a">="b”))

另外:$?是shell变量,表示"最后一次执行命令"的退出状态.0为成功,非0为失败.

shell脚本中if的“-e,-d,-f”

文件表达式
-e filename 如果 filename存在,则为真
-d filename 如果 filename为目录,则为真
-f filename 如果 filename为常规文件,则为真
-L filename 如果 filename为符号链接,则为真
-r filename 如果 filename可读,则为真
-w filename 如果 filename可写,则为真
-x filename 如果 filename可执行,则为真
-s filename 如果文件长度不为0,则为真
-h filename 如果文件是软链接,则为真
filename1 -nt filename2 如果 filename1比 filename2新,则为真。
filename1 -ot filename2 如果 filename1比 filename2旧,则为真。

整数变量表达式
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于

字符串变量表达式
If [ $a = $b ] 如果string1等于string2,则为真
字符串允许使用赋值号做等号
if [ $string1 != $string2 ] 如果string1不等于string2,则为真
if [ -n $string ] 如果string 非空(非0),返回0(true)
if [ -z $string ] 如果string 为空,则为真
if [ $sting ] 如果string 非空,返回0 (和-n类似)

逻辑非 !                   条件表达式的相反

if [ ! 表达式 ]
if [ ! -d n u m ] 如果不存在目录 num ] 如果不存在目录 num]如果不存在目录num

逻辑与 –a                   条件表达式的并列

if [ 表达式1 –a 表达式2 ]

逻辑或 -o                   条件表达式的或

if [ 表达式1 –o 表达式2 ]

rm -f $1~

-f :即使文件只读也删除且不询问

Shell脚本编写规范

脚本文件后缀名规范

shell脚本文件就是一个文本文件, 后缀名建议使用 .sh 结尾.
扩展名并不影响脚本执行,见名知意就好,如果你用 php 写 shell 脚本,扩展名就用 php 好了

首行格式规范

首行需要设置Shell解析器的类型, 语法

#!/bin/bash

含义: 设置当前shell脚本文件采用bash解析器运行脚本代码

注释格式

单行注释, 语法

# 注释内容

多行注释, 语法

:<<!
# 注释内容1
# 注释内容2
!

shell脚本HelloWord入门案例

需求
创建一个Shell脚本文件hello.sh,输出hello shell world字符串

效果

  1. 创建shell脚本文件
touch hello.sh
  1. 编辑文件
vim helloworld.sh
  1. 增加脚本内容
#!.bin/bash
echo "hello shell word
  1. 执行脚本
sh hello.sh

脚本文件的常用执行3种方式

介绍

  1. sh解析器执行方式
    语法: sh 脚本文件
    介绍: 就是利用sh命令执行脚本文件, 本质就是使用Shell解析器运行脚本文件
  2. bash解析器执行方式
    语法: bash 脚本文件
    介绍: 就是利用bash命令执行脚本文件, 本质就是使用Shell解析器运行脚本文件
  3. 仅路径执行方式
    语法: ./脚本文件
    介绍: 执行当前目录下的脚本文件
    注意: 脚本文件自己执行需要具有可执行权限, 否则无法执行

3种方式的区别
​ sh或bash执行脚本文件方式是直接使用Shell解析器运行脚本文件, 不需要可执行权限

​ 仅路径方式是执行脚本文件自己, 需要可执行权限
参考:https://blog.csdn.net/m0_51340928/article/details/109233357

chmod 修改文件属性

在linux终端输入ls -l,可以看到如:
在这里插入图片描述
-rwx-r–r-- (一共10个参数)
表示文件所属组和用户的对应权限。

  1. 第一个跟参数属于管理员,跟chmod无关,表示文件的属性: d:表示是一个文件夹 l:表示是一个链接
    -:表示是一个普通的文件 注意:这是第一位和后面的不一样
  2. 2-4参数:属于user
  3. 5-7参数:属于group
  4. 8-10参数:属于others

用数字来分配权限

r==>可读 w==>可写 x==>可执行()execute
r=4 w=2 x=1

chmod是Linux下设置文件权限的命令,后面的数字表示不同用户或用户组的权限。
一般是三个数字:

第一个数字表示文件所有者的权限
第二个数字表示与文件所有者同属一个用户组的其他用户的权限
第三个数字表示其它用户组的权限。
权限分为三种:
读(r=4),写(w=2),执行(x=1)。
综合起来还有可读可执行(rx=5=4+1)、可读可写(rw=6=4+2)、可读可写可执行(rwx=7=4+2+1)。

所以:
755代表 rwxr-xr-x 当前用户可读可执行。
777 代表 rwxr-rwx-rwx 所有用户都可读可写可执行。

所以,chmod 755 设置用户的权限为:

文件所有者可读可写可执行
与文件所有者同属一个用户组的其他用户可读可执行
其它用户组可读可执行
chmod 4755与chmod 755 的区别在于开头多了一位,这个4表示其他用户执行文件时,具有与所有者相当的权限。

用字母来分配权限:chmod 的相对用法
我们还可以用字母来分配权限,原理相似,但是又是不必写出所有的三组权限都写出来。有时候比较灵活
我们先来看不同字母代表的含义:

u:user 的缩写,表示所有者;
g:group 的缩写,表示群组用户;
o:other 的缩写,表示其他用户;
a:all 的缩写,表示所有用户。

和这些字母配合的还有几个符号:
+:加号,表示添加权限;
-:减号,表示去除权限;
=:等号,表示分配权限。

#文件 file.txt 的所有者增加读和运行的权限。
chmod u+rx file.txt

#文件 file.txt 的群组其他用户增加读的权限。
chmod g+r file.txt 

#文件 file.txt 的其他用户移除读的权限。
chmod o-r file.txt 

#文件 file.txt 的群组其他用户增加读的权限,其他用户移除读的权限。
chmod g+r o-r file.txt 

#文件 file.txt 的群组其他用户和其他用户均移除读的权限。
chmod go-r file.txt 

#文件 file.txt 的所有用户增加运行的权限。
chmod +x file.txt 

#文件 file.txt 的所有者分配读,写和执行的权限;
#群组其他用户分配读的权限,不能写或执行;
#其他用户没有任何权限。
chmod u=rwx,g=r,o=- file.txt

参考内容:https://blog.csdn.net/rjszz1314/article/details/104399333
https://blog.csdn.net/rjszz1314/article/details/104399333

shell变量

定义变量时,变量名不加美元符号($,PHP语言中变量需要),如

your_name="runoob.com"

注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样
除了显式地直接赋值,还可以用语句给变量赋值,如:

for file in `ls /etc`for file in $(ls /etc)

以上语句将 /etc 下目录的文件名循环出来。

使用变量

使用一个定义过的变量,只要在变量名前面加美元符号即可,如:

your_name="qinjx"
echo $your_name
echo ${your_name}

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

for skill in Ada Coffe Action Java; do
    echo "I am good at ${skill}Script"
done
只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
下面的例子尝试更改只读变量,结果报错:

#!/bin/bash

myUrl="https://www.google.com"
readonly myUrl
myUrl="https://www.runoob.com"
/bin/sh: NAME: This variable is read only.
删除变量

使用 unset 命令可以删除变量。语法:

unset variable_name

变量被删除后不能再次使用。unset 命令不能删除只读变量

Shell 字符串

字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。
单引号字符串的限制:

单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

双引号的优点:

双引号里可以有变量
双引号里可以出现转义字符

Shell echo命令

Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出。命令格式:

echo string

您可以使用echo实现更复杂的输出格式控制。

1.显示普通字符串:
echo "It is a test"
#双引号完全可以省略,,效果一样。
2.显示转义字符
echo "\"It is a test\""

结果将是:

"It is a test"

同样,双引号也可以省略

3.显示变量

read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量

#!/bin/sh
read name 
echo "$name It is a test"

以上代码保存为 test.sh,name 接收标准输入的变量,结果将是:

[root@www ~]# sh test.sh
OK                     #标准输入
OK It is a test        #输出
4.显示换行
echo -e "OK! \n" # -e 开启转义
echo "It is a test"

输出结果:

OK!

It is a test
5.显示不换行
#!/bin/sh
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo "It is a test"

输出结果:

OK! It is a test
6.显示结果定向至文件
echo "It is a test" > myfile
7.原样输出字符串,不进行转义或取变量(用单引号)
echo '$name\"'

输出结果:

$name\"
8.显示命令执行结果
echo `date`

注意: 这里使用的是反引号 `, 而不是单引号 '。

结果将显示当前日期

Thu Jul 24 10:08:46 CST 2014

Shell 流程控制

和 Java、PHP 等语言不一样,sh 的流程控制不可为空。
在 sh/bash 里如果 else 分支没有语句执行,就不要写这个 else。

if else

fi
if 语句语法格式:

if condition
then
    command1 
    command2
    ...
    commandN 
fi

写成一行(适用于终端命令提示符):

if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi

末尾的 fi 就是 if 倒过来拼写,后面还会遇到类似的。

if else-if else

if else-if else 语法格式:

if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi

if else 的 […] 判断语句中大于使用 -gt,小于使用 -lt。

if [ "$a" -gt "$b" ]; then
    ...
fi
a=10
b=20
if [ $a == $b ]
then
   echo "a 等于 b"
elif [ $a -gt $b ]
then
   echo "a 大于 b"
elif [ $a -lt $b ]
then
   echo "a 小于 b"
else
   echo "没有符合的条件"
fi

如果使用 ((…)) 作为判断语句,大于和小于可以直接使用 > 和 <。

if (( a > b )); then
    ...
fi
a=10
b=20
if (( $a == $b ))
then
   echo "a 等于 b"
elif (( $a > $b ))
then
   echo "a 大于 b"
elif (( $a < $b ))
then
   echo "a 小于 b"
else
   echo "没有符合的条件"
fi

if else 语句经常与 test 命令结合使用,如下所示

num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
    echo '两个数字相等!'
else
    echo '两个数字不相等!'
fi
for 循环

与其他编程语言类似,Shell支持for循环。
for循环一般格式为:

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

写成一行:

for var in item1 item2 ... itemN; do command1; command2… done;
while 语句

while 循环用于不断执行一系列命令,也用于从输入文件中读取数据。其语法格式为:

while condition
do
    command
done

以下是一个基本的 while 循环,测试条件是:如果 int 小于等于 5,那么条件返回真。int 从 1 开始,每次循环处理时,int 加 1。运行上述脚本,返回数字 1 到 5,然后终止。

实例

#!/bin/bash
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done

以上实例使用了 Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量,具体可查阅:Bash let 命令
while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按<Ctrl-D>结束循环。

echo '按下 <CTRL-D> 退出'
echo -n '输入你最喜欢的网站名: '
while read FILM
do
    echo "是的!$FILM 是一个好网站"
done

VCS指令

1、+incdir+
+incdir+ `include文件的搜索目录。
-incdir 在指定目录下搜索include文件
方便在
2、-v filename
-v 指定一个.v格式的库文件,VCS会来这个文件中找源代码中例化的但在源代码中找不到的module,这里一个文件可以里面包含很多module。
filelist列表中 -v xxx/xxx/fifo.v 表示该文件里面只有一个module,且module名为fifo。
filelist列表中直接引用 xxx/xxx/fifo.v 则对文件中的module名没有限制。
3、-y directory
-y 指定一个库文件目录,目录下的文件名和module名要一致,且要用+libext+来指定文件类型,这里的.v文件里面就只能放一个和文件名同名的module,VCS会来这个目录下找源代码中例化的但在源代码中找不到的module。
4、+libext+
+libext+ .v+ .vg+ .sv 指定文件类型。
5、-f filename
指定文件类型为.f。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐