Shell脚本初始

shell初识

Shell(Unix Shell)是一种命令行解释器,是Unix操作系统下最传统的人机接口。Shell脚本是解释执行的,不需要编译,和大部分的编程语言很相似,也有基本的变量和流程控制语句。我们平时使用Shell有两种方式:

  • 1、输入命令,执行,这种方式称为交互式
  • 2、批处理方式,用户事先写好shell脚本,然后顺序批次执行

第一个Shell环境是ThompsonShell,在贝尔实验室开发并于1971年发布。 现代Shell最突出的祖先是被称为sh的BourneShell,这是以在AT&T工作的创始人stephenBourne命名的

go 复制代码
shell`一直基于这个概念,不断添加各种新功能,演变出很多`shell

例如,很早版本的OS X中使用的是tcsh作为默认的shell,这是由csh(c shell),一种C语言演变而来

os x 10.3版本之后,默认的shellbash

除了默认的bash,现在macos中,默认的Shell变成了zsh。这是一种由Paul Falstad于1990年开发的。它是一个BourneShell,它使用bash和previous shell的特性,并添加了更多的特性:

  • 拼写检查功能
  • 内置的编程特性
  • 友好的交互

确认当前终端tty使用的shell类型

于此同时,macOS还提供了很多种其他类型的shell

运行shell脚本

  • 1、进入所在目录,然后输入命令./test.sh

  • 2、直接将.sh拖到终端

    bash 复制代码
    #!/bin/bash
    echo "Hello World !"

    #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell

    echo 命令用于向窗口输出文本。

.zshrc .bashrc .bash_profile 的区别

在使用命令行工具时,我们可能会遇到一些教程,可能需要你把一些配置写入到.bashrc.bash_profile或者.zshrc等。那么这几个文件到底有什么作用和区别?

首先,从文件名称判断.bashrc、.bash_profile是给Bash来使用的。而.zshrc是给zsh来使用的。

交互式登录和非登录Shell

当调用Shell时,Shell从一组启动文件中读取信息并执行命令。读取什么文件取决于Shell是作为交互式登录还是非登录调用

换而言之,Shell分为交互式的或者非交互式的

  • 交互式Shell是读取和写入到用户终端的Shell程序,用户在终端输入命令,并在回车后立即执行
  • 非交互式Shell是与终端不相关的Shell程序,如脚本执行

当作为交互式登录Shell调用时,Bash会先查找/etc/profile文件,如果该文件存在,它将运行文件中列出的命令。然后,搜索~/.bashprofile ~/.bash_login以及~/.profile文件,顺序读取。

Bash作为交互式非登录shell调用时,会读取~/.bashrc

所以说,.bashrc和.bash_profile之间的区别是,.bash_profileBash作为交互式登录shell调用时被读取并执行,而.bashrc对于交互式非登录shell被执行。

确认当前是登录还是非登录shelltty中执行echo $0,输出的Shell如果前面带-,说明是登录Shell。

建议配置

复制代码
    1、bash
  • 将配置选项放到~/.bashrc中,然后在~/.bash_profile中通过source调用。
复制代码
    2、zsh
  • 建议仍然将配置选项放到~/.bashrc~/.bash_profile中通过source调用,最后在~/.zshrcsource调用~/.bash_profile.

shell基础语法

1、变量

定义变量时,变量名不加美元符号

ini 复制代码
name="xiaoming"

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

bash 复制代码
echo $name
echo ${name}

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界

2、Shell 字符串

字符串是shell编程中最常用最有用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号。

ini 复制代码
str='this is a string'
str1="this is a string"

拼接字符串

bash 复制代码
echo "hello ${name}"

获取字符串长度

ini 复制代码
str='this is a string'
echo ${#str}

提取子字符串

php 复制代码
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

3、Shell 数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。

ini 复制代码
array_name=(value0 value1 value2 value3)
# 读取数组元素
echo $array_name[0]
# 取得数组元素的个数
length1=${#array_name[@]}
echo $length1
# 或者
length2=${#array_name[*]}
echo $length2

4、Shell 注释

# 开头的行就是注释,会被解释器忽略。

shell 复制代码
##### 用户配置区 开始 #####
#
#
# 这里可以添加脚本描述信息
# 
#
##### 用户配置区 结束  #####

多行注释

多行注释还可以使用以下格式:

bash 复制代码
:<<EOF
注释内容...
注释内容...
注释内容...
EOF

5、Shell 传递参数

我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为: $nn 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推......

bash 复制代码
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
echo "传递到脚本的参数个数:$#";
echo "传递的参数作为一个字符串显示:$*";
echo "-- $* 演示 ---"
for i in "$*"; do
    echo $i
done

echo "-- $@ 演示 ---"
for i in "$@"; do
    echo $i
done

Shell运算符

Shell 和其他编程语言一样,支持多种运算符,包括:

  • 算数运算符
  • 关系运算符
  • 布尔运算符
  • 字符串运算符
  • 文件测试运算符

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

算数运算符

bash 复制代码
#!/bin/bash
​
a=10
b=20
​
# +
val1=`expr $a + $b`
echo "a + b : $val1"
​
# -
val=`expr $a - $b`
echo "a - b : $val"
​
# *
val3=`expr $a * $b`
echo "a * b : $val3"
​
# /
val4=`expr $b / $a`
echo "b / a : $val4"
​
# %
val5=`expr $b % $a`
echo "b % a : $val5"
​
# 判等
if [ $a == $b ]
then
   echo "a 等于 b"
fi
if [ $a != $b ]
then
   echo "a 不等于 b"
fi

关系运算符

运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ <math xmlns="http://www.w3.org/1998/Math/MathML"> a − e q a -eq </math>a−eqb ] 返回 false。
-ne 检测两个数是否不相等,不相等返回 true。 [ <math xmlns="http://www.w3.org/1998/Math/MathML"> a − n e a -ne </math>a−neb ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ <math xmlns="http://www.w3.org/1998/Math/MathML"> a − g t a -gt </math>a−gtb ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ <math xmlns="http://www.w3.org/1998/Math/MathML"> a − l t a -lt </math>a−ltb ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ <math xmlns="http://www.w3.org/1998/Math/MathML"> a − g e a -ge </math>a−geb ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ <math xmlns="http://www.w3.org/1998/Math/MathML"> a − l e a -le </math>a−leb ] 返回 true。
bash 复制代码
if [ $a -eq $b ]
then
   echo "$a -eq $b : a 等于 b"
else
   echo "$a -eq $b: a 不等于 b"
fi

if [ $a -ne $b ]
then
   echo "$a -ne $b: a 不等于 b"
else
   echo "$a -ne $b : a 等于 b"
fi

if [ $a -gt $b ]
then
   echo "$a -gt $b: a 大于 b"
else
   echo "$a -gt $b: a 不大于 b"
fi

if [ $a -lt $b ]
then
   echo "$a -lt $b: a 小于 b"
else
   echo "$a -lt $b: a 不小于 b"
fi

if [ $a -ge $b ]
then
   echo "$a -ge $b: a 大于或等于 b"
else
   echo "$a -ge $b: a 小于 b"
fi

if [ $a -le $b ]
then
   echo "$a -le $b: a 小于或等于 b"
else
   echo "$a -le $b: a 大于 b"
fi

布尔运算符

运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ <math xmlns="http://www.w3.org/1998/Math/MathML"> a − l t 20 − o a -lt 20 -o </math>a−lt20−ob -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ <math xmlns="http://www.w3.org/1998/Math/MathML"> a − l t 20 − a a -lt 20 -a </math>a−lt20−ab -gt 100 ] 返回 false。
bash 复制代码
if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"
else
   echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
   echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
   echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
   echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
   echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
   echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
   echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi

字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":

运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ <math xmlns="http://www.w3.org/1998/Math/MathML"> a = a = </math>a=b ] 返回 false。
!= 检测两个字符串是否不相等,不相等返回 true。 [ <math xmlns="http://www.w3.org/1998/Math/MathML"> a ! = a != </math>a!=b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否不为 0,不为 0 返回 true。 [ -n "$a" ] 返回 true。
$ 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。
bash 复制代码
a="abc"
b="efg"

if [ $a = $b ]
then
   echo "$a = $b : a 等于 b"
else
   echo "$a = $b: a 不等于 b"
fi

if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"
else
   echo "$a != $b: a 等于 b"
fi

if [ -z $a ]
then
   echo "-z $a : 字符串长度为 0"
else
   echo "-z $a : 字符串长度不为 0"
fi

if [ -n "$a" ]
then
   echo "-n $a : 字符串长度不为 0"
else
   echo "-n $a : 字符串长度为 0"
fi

if [ $a ]
then
   echo "$a : 字符串不为空"
else
   echo "$a : 字符串为空"
fi

文件测试运算符

操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。
bash 复制代码
file="/Users/jiangjunhui/Desktop/test.sh"
if [ -r $file ]
then
   echo "文件可读"
else
   echo "文件不可读"
fi

if [ -w $file ]
then
   echo "文件可写"
else
   echo "文件不可写"
fi

if [ -x $file ]
then
   echo "文件可执行"
else
   echo "文件不可执行"
fi

if [ -f $file ]
then
   echo "文件为普通文件"
else
   echo "文件为特殊文件"
fi

if [ -d $file ]
then
   echo "文件是个目录"
else
   echo "文件不是个目录"
fi

if [ -s $file ]
then
   echo "文件不为空"
else
   echo "文件为空"
fi

if [ -e $file ]
then
   echo "文件存在"
else
   echo "文件不存在"
fi
相关推荐
ilmari5 分钟前
HarmonyOS 基于Network Kit封装的网络请求工具
android·flutter·harmonyos
Digitally2 小时前
如何通过 5 种方式将照片从 iPad 传输到电脑
ios·电脑·ipad
Sugobet6 小时前
【安卓][Mac/Windows】永久理论免费 无限ip代理池 - 适合临时快速作战
android·tcp/ip·macos·网络安全·渗透测试·ip代理池·接入点
fatiaozhang952710 小时前
创维智能融合终端SK-M424_S905L3芯片_2+8G_安卓9_线刷固件包
android·电视盒子·刷机固件·机顶盒刷机
来来走走10 小时前
Flutter开发 了解Scaffold
android·开发语言·flutter
哆啦A梦的口袋呀12 小时前
Android 底层实现基础
android
闻道且行之12 小时前
Android Studio下载及安装配置
android·ide·android studio
alexhilton12 小时前
初探Compose中的着色器RuntimeShader
android·kotlin·android jetpack
小墙程序员12 小时前
kotlin元编程(二)使用 Kotlin 来生成源代码
android·kotlin·android studio
小墙程序员13 小时前
kotlin元编程(一)一文理解 Kotlin 反射
android·kotlin·android studio