shell 用法入门

简介: 本文档详细介绍了Shell脚本的基础知识,包括基本写法、变量定义与使用、命令置换、环境变量、数组操作、算术运算、输入输出处理、控制语句及循环结构等内容。文档还提供了丰富的示例代码,帮助读者更好地理解和掌握Shell编程技巧。此外,还介绍了如何使用`if`语句进行条件判断、`case`语句进行模式匹配以及`while`、`for`循环等控制结构。最后,文档还涵盖了函数定义与调用的方法。适合初学者和有一定基础的开发者参考学习。

shell

基本写法

#!/bin/bash # 指定 shell 解释器
ls # 执行命令

脚本执行

chmod +x script.sh # 使脚本可执行

4种方式:

  1. 直接运行脚本 ./script.sh
  2. bash 运行脚本 bash script.sh
  3. source 运行脚本 source script.sh
  4. 使用 . (空格)脚本名称 来执行

三种方式的区别:

  1. ./script.sh 新创建的脚本,默认没有x执行权限,需要给它用#chmod +x test.sh的方式,添加执行权限。在生产环境中不要轻易的给文件可执行权限;

  2. bash script.sh 该方式虽然不需要手动给脚本添加x执行权限,但是它会改变脚本默认解释器类型。比如说:脚本首行定义的是#!/bin/bash,使用该方式,它会给你改用/bin/sh解释器,也就说,最终效果=#!/bin/bash --posix

特别之处:该方式 1.不需单独给脚本分配x执行权限;2.甚至都不需要在脚本首行声明脚本解释器类型,因为脚本是被当做该命令的参数使用的。

  1. source script.sh .和source的权限,继承的是/bin/bash的权限,在执行时也是将test.sh作为参数,并不需要test.sh有执行权限;
    和bash执行不一样的是,source和.不会创建子进程,是在当前shell进程下执行的,因为他们是内建命令,所以脚本中赋值的本地变量也会影响当前shell的,用的时候一定要注意(尽量使用前面的3种方式)。

  2. 使用 . (空格)脚本名称 来执行, 该方式,不需要单独添加x执行权限,它和source类似,权限继承与bash。

区别

相对路径、绝对路径执行方法,需要chmod +x test.sh,给脚本单独添加x执行权限。
后2种方法,均不需要单独添加x执行权限。

相对路径、绝对路径执行方法,脚本执行时会开启一个子shell环境,在子shell执行完后,子shell环境随即关闭,然后又回到当前shell中。
后面两种. 和source方式,则是在当前shell中执行,不会开启子shell。

练习

#1.在自己的用户主目录下新建两个子目录subdir1 subdir2 
#2.将/etc/passwd文件拷贝到subdir1 ,将/etc/group拷贝到subdir2 
#3.将subdir2重命名为subdir 
#4.对subdir1进行打包并且压缩成xz格式 
#5.将打包后的xz格式文件拷贝到subdir目录下 
#6.解压subidr目录下的压缩格式文件 
#7.查看subidr目录下所有的文件
#!/bin/bash
cd ~
mkdir subdir1 subdir2
cp /etc/passwd ~/subdir1/
cp /etc/group ~/subdir2/
mv subdir2  subdir 
tar -cJvf subdir1.tar.xz subdir1
cp subdir1.tar.xz subdir/
cd subdir
tar -xvf subdir1.tar.xz
ls -l

shell中的变量 ${变量名}

shell中的变量没有类型,使用的时候也不要定义。shell中的

变量在赋值的时候使用=(前后不能有空格),在shell脚本中

值默认都是字符串。

变量定义和赋值

#!/bin/bash
var1=123                                                                                     
var2=abc  #在shell脚本中给变量赋值的时候不能再等号前后出现空格
var3='hello world' #如果值字符串中有空格需要使用单引号
var4="test $var2"  #如果值字符串中有获取变量值过程使用双引号
echo $var1
echo $var2
echo $var3
echo $var4
`

获取变量的值

使用$变量名获取变量的值。或者使用${变量名}获取变量的值。

$变量名

${变量名}

使用shell脚本对var1和var2进行交换

#!/bin/bash
var1=123
var2=abc

var3=$var1
var1=$var2
var2=$var3

位置变量

$0 表示脚本名,$1表示第一个参数,$2表示第二个参数,以此类推。
$*或$@:代表的是命令行所有的参数
$#:代表的是命令行参数的个数

#!/bin/bash
echo "脚本名:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"
echo "所有参数:$*"
echo "参数个数:$#"

命令置换 变量名=ls 变量名=$(ls)

命令置换是指在shell脚本中,将命令的输出结果赋值给变量。

#!/bin/bash
var1=`ls`  #将ls的结果赋值给var1
var2=$(ls /) #将ls /的结果赋值给var2变量

echo "$var1"
echo "*********************************"
echo "$var2"

环境变量

环境变量是指在系统中预先定义好的变量,这些变量在shell脚本中可以直接使用。

env 查看所有的环境变量

echo ${PATH} 只查看PATH环境变量

HOME:存放当前用户家目录的环境变量

USERNAME:存放当前用户的用户名

PATH:存放ubuntu系统可执行程序(命令)的路径


#!/bin/bash
var1=${HOME}
var2=${PATH}

echo $var1
echo $var2

export PATH=${PATH}:/home/linux/ #export修改的环境变量可以作用当前终端,需要使用source执行

注:如果想要永久修改系统的PATH,可以在如下文件中修改

sudo vi /etc/environment
或者

sudo vi ~/.bashrc在这个文件中添加如下语句

export PATH=${PATH}:/home/linux/

数组

数组是一种特殊的变量,可以存储多个值。

数组的定义格式为:

成员和成员间是空格分隔的

数组名=(值1 值2 值3...)

arr=(11 22 33 abc)

数组的索引从0开始。

数组的操作

#!/bin/bash

#定义数组
arr=(1 2 3 4 5)



#获取数组的长度
length=${#arr[@]}
echo "数组的长度为:$length"



#获取数组的第n个元素
echo "数组的第1个元素为:${arr[0]}"
echo "数组的第2个元素为:${arr[1]}"
echo "数组的第3个元素为:${arr[2]}"
echo "数组的第4个元素为:${arr[3]}"
echo "数组的第5个元素为:${arr[4]}"



#获取数组的所有元素
echo "数组的所有元素为:"
for i in ${arr[@]}
do
    echo $i
done


#获取数组中成员所占的字节数
echo "数组中成员所占的字节数:"
for i in ${#arr[@]}
do
    echo ${#arr[$i]}

done

数组拼接

#!/bin/bash
arr1=(abc 123)
arr2=(www tttt hhhh)

arr1=(${arr1[*]} ${arr2[@]}) #将arr2拼接到arr1的结尾
echo ${arr1[*]} #abc 123 www tttt hhhh
arr1=(${arr1[0]} ${arr2[@]} ${arr1[1]}) #将arr2插入到arr1[0]和arr1[1]之间
echo ${arr1[*]}  #abc www tttt hhhh 123
#!/bin/bash
arr=(`ls`)
echo "当前目录下文件个数=${#arr[*]}"

shell中算术运算

在shell脚本中可以进行整数的算术运算,shell脚本的变量默认都是

字符串,所以需要使用以下的运算符号进行算术运算。shell脚本中

不能进行浮点运算。

(())

ret=$[]

expr

(())

(())进行算术运算效率最高,支持c语言的各种写法。

#!/bin/bash

((sum=3+4))  #将3+4的结果赋值给sum
echo $sum

var1=123
var2=456
((sum=var1+var2)) #在使用(())进行算数运算时变量加不加$都是可以正常执行的
echo $sum

((sum=$var1+$var2))
echo $sum

n=0
((n++))  #可以进行自加运算
echo $n

((mul=3*4)) #shell脚本中的乘运算
echo $mul

((mul=3**4)) #shell脚本中的幂运算
echo $mul

i=10
sum=100
((sum+=i++)) #c语言的运算表达式在shell中也是支持的
echo "$sum----$i" 

sum=$((5+10)) #将算术运算的结果赋值给sum变量时候需要加$符号
echo $sum

$[]

在使用$[]进行算术运算的时候表达式格式必须是ret=$[运算的表达式],效率没有(())高。

#!/bin/bash
sum=$[3+4]
echo $sum

var1=123
var2=456
sum=$[var1+var2]
echo $sum

sum=$[$var1+$var2]
echo $sum

mul=$[3*4]
echo $mul

mul=$[3**4]  #3*3*3*3
echo $mul

n=0
#$[n++]  这种写法是错误的                           
#echo $n
n=$[n+1]
echo $n

expr

expr在使用的时候严格注意格式,expr在进行算术运算的时候效率没有(())和$[]效率高。

#!/bin/bash
expr 3+4  #expr本身自带打印功能,如果+运算符前后没有空格不进行算术运算
          #表达式的结果是3+4
expr 3 + 4 #进行算数运算,将运算的结果打印到终端上

var1=123
var2=456
expr $var1 + $var2  #在使用expr进行算数运算的时候变量前必须加$符号

expr 3 \* 4  #expr在进行乘运算的时候需要加\进行转义,否则会认为*是通配符号

#expr 3 ** 4  #expr不支持幂运算 

sum=`expr 3 \* 4` #将expr表达式赋值给变量的时候需要使用命令置换
sum=$(expr 3 \* 4)
echo $sum

expr可以进行字符串的操作

```shell

!/bin/bash

str="www.hqyj.com"

expr match $str "www.hq"

拿后面的字符串和前面的字符串进行比较如果完全相同返回子字符串长度

expr match $str "w1w.hq"

拿后面的字符串和前面的字符串进行比较如果不同返回0

expr substr $str 1 5

从str中提起字符串,1表示从第一个字符开始,5提取5个字符

expr index $str 'h'

获取h字符在str中的下标,上述表达式的结果返回5

expr length $str

获取str字符串中字符的个数

echo ${#str}

这个方式也可以获取str所占的字节的个数


## 输入输出
### read输入
read命令从标准输入(键盘)读取数据,并将其存储在变量中。

```shell
#!/bin/bash

echo "请输入你的名字:"
read name
echo "你好,$name!"

read -p "提示语" 变量名

-p选项可以指定提示语。

#!/bin/bash

read -p "请输入你的名字:" name
echo "你好,$name!"

向arr中输入数组元素

#!/bin/bash
read -p "input arr > "  -a  arr  #通过终端向arr输入数组
echo ${arr[*]}  #打印数组中所有的成员
echo ${arr[2]}  #打印下标位2对应的数组的成员

使用静默模式向变量中输入字符串

#!/bin/bash
read -s -p "请输入密码:" password
echo "你的密码是:$password"

read -n 个数 变量

输入n个字符自动停止

#!/bin/bash
read -p "input str > " -n 3 str  #在终端输入三个字符后自动结束输入
echo 
echo $str

read -t 秒数 变量

设置等待时间,如果在指定时间内没有输入,则自动结束输入。

#!/bin/bash
read -p "input str > " -t 3 str  #在3秒内输入字符串,如果在3秒内没有输入,则自动结束输入
echo 
echo $str

输出

echo 输出

echo 变量1 变量2 ...

#!/bin/bash

echo "hello world"

echo -e 输出 会解析转义字符

-e选项可以输出颜色和样式。

#!/bin/bash

echo -e "\033[1;31m hello world \033[0m"

echo -n 输出

-n选项可以输出字符串时不换行。

#!/bin/bash

echo -n "hello world"

控制语句

if/else 控制语句

#用法1
if [ 表达式 ]   ==> if test 表达式
then
 语句成立执行当前代码块
fi
#用法2
if [ 表达式 ] 
then
 表达式成立执行当前代码块
else
 表达式不成立执行else代码块
fi
#用法3
if [ 表达式1 ]
then
 代码块1
elif [ 表达式2 ]
then
 代码块2
elif [ 表达式3 ]
then
 代码块3
else
 代码块4
fi

if对象判断方法

字符串对象

进行字符串的判断的时候都需要加上""
    -z 判断字符串是否为空            
    -n 判断字符串是否为非空        
    =或== 都是用来判读字符串是否相等  
    !=    不等于           
    \>    大于 (防止误认为重定向)  
    \<    小于

数字对象

    -eq : 等于     
    -ne : 不等于    
    -gt : 大于      
    -lt : 小于  
    -ge : 大于等于  
    -le : 小于等于

文件对象

    -b filename 判断文件是否存在,是否是块设备    
    -c filename 判断文件是否存在,是否是字符设备  
    -d filename 判断文件是否存在,是否是目录      
    -f filename 判断文件是否存在,是否是普通文件   
    -p filename 判断文件是否存在,是否是管道文件   
    -L filename 判断文件是否存在,是否是链接文件 (经测试链接文件也是普通文件)
    -S filename 判断文件是否存在,是否是套接字文件 
    -e filename 判断文件是否存在
    -s filename 判断文件是否存在,判断文件是否为空

文件权限对象

    -r filename 判断文件是否存在,是否有可读权限 
    -w filename 判断文件是否存在,是否有可写权限  
    -x filename 判断文件是否存在,是否有可执行权限

文件比较运算

    -nt  文件是否更新 
    -ot  文件是否更旧 
    -ef  文件的inode是否一致

逻辑运算

    -a   与   
    -o   或  
    !    非

使用示例

shell_ifelse使用示例.md

case/in语句

case 变量 in
 匹配项1)
  语句块1
  ;;
 匹配项2)
  语句块2
  ;;
  *)
  语句块n
  ;;
esac

case/in匹配项的写法

通配符

*:所有的任意的字符

[0-9]或[a-z]或者[abxyz]匹配[]内的任意一个字符

[^abc]:表示匹配除abc之外的任意一个字符

?:通配任意一个字符

在匹配项中可以使用|运算符

"YES"|"yes"|"Y"|"y")

使用示例

#!/bin/bash
echo "输入1或2:"
read num
case $num in
1|2)
 echo "你输入的数字是$num"
 ;;
*)
 echo "你输入的数字不是1或2"
 ;;
esac

输入年和月输出这个月有多少天

#!/bin/bash
read -p "input (year month) > " year month

case $month in
    1|3|5|7|8|10|12)
        echo "$year-$month has 31 day!"
        ;;
    4|6|9|11)
        echo "$year-$month has 30 day!"
        ;;
    2)  
        if (((year%4==0&&year%100!=0) || (year%400==0)))
        #if [ $((year%4)) -eq 0  -a $((year%100)) -ne 0 -o $((year%400)) -eq 0 ]
        then
            echo "$year-$month has 29 day!"
        else
            echo "$year-$month has 28 day!"
        fi
        ;;
    *)  
        echo "input error,try again"          
        ;;
esac

while循环

while [ 表达式 ]
do
 语句块
done

示例

#!/bin/bash
i=1
while [ $i -le 10 ] 
do
 echo $i
 ((i++))
done

for循环

#用法1
for ((i=0;i<100;i++))
do
 循环体
done

#用法2
for 变量 in 参数列表
do
 循环体
done

#用法3
for 变量    #将位置变量作为参数列表
do
 循环体
done

示例

#!/bin/bash
i=0
sum=0

for ((i=0;i<=100;i++))
do
    ((sum+=i))
done                                                                           

echo $sum


for i in 1 2 3 4 5
do
    echo $i
done

for file in `ls`
do
    echo $file
done

select/in循环

select 变量 in 列表
do
 语句
done

示例

#!/bin/bash
export PS3="input >" #修改选择提示符 
select item in 1 2 3 4 5
do
    echo "你选择的选项是:$item"
done

break语句

break n #退出n层循环

#!/bin/bash
i=1
while [ $i -le 10 ] 


 do
    echo $i
    ((i++))
    if [ $i -eq 5 ]
    then
        break  #退出当前循环
    fi
done
#!/bin/bash
i=0
while true
do
    echo "这是外循环"
    sleep 1
    while true
    do
        echo "这是内循环"
        sleep 1
        ((i++))
        if [ $i -ge 5 ] 
        then
            break 2   #退出两层循环  
        fi
    done
done

continue语句

continue n #结束n层当前循环,进而执行下一次循环

#!/bin/bash
i=0
while true
do
    echo "这是外循环"
    sleep 1
    while true
    do
        echo "这是内循环"
        sleep 1
        ((i++))
        if [ $i -ge 5 ] 
        then
            continue 2 
        fi
    done
done

函数

function 函数名()
{
 函数体
 return 结果
}

function是用来声明函数的,这里的function是可以省略的,但是习惯上是需要写function的

函数命名规则和c语言的函数命名规则是一样的

shell中的函数没有参数列表但是可以通过位置变量传参

$0 $1..$9..${n}

$*或$@或$#

shell中的函数体通过{}包括

shell中的函数可以通过return返回[0-255]区间内的结果,如果要返回其他值通过echo完成

shell的函数调用方法,shell中的函数只有调用才会执行

函数名 参数1 参数2...

示例

#!/bin/bash

#定义函数
function my_func()
{
    echo "hello world"
}


#调用函数
my_func

示例

实现多个数求和的函数

#!/bin/bash

function add()
{
    var1=1
    var2=$1
    #echo $0  #这里的$0不是函数名,而是脚本的名字
    local sum=0
    ((sum=$var1+$var2))
    return $sum #这里return的时候只能返回0-255之间的数
}

add 256 
echo $? #获取上一步执行的结果
echo $sum
#在函数内定义的变量默认是全局变量,如果在变量前加了local表示它是局部变量
相关文章
|
6月前
|
存储 运维 Shell
shell中for while until 三种循环的用法
shell编程中,有几种常见的循环结构,包括for循环、while循环和until循环,总的来说,循环shell编程中扮演着至关重要的角色,它们使得自动化任务变得更加容易,提高了效率,并且可以处理各种各样的编程需求。
316 13
shell中for while until 三种循环的用法
|
6月前
|
人工智能 机器人 Shell
【shell】文件读写及read用法
【shell】文件读写及read用法
|
6月前
|
Shell Linux
Linux下的Shell基础——Shell概述和入门(一)
Linux下的Shell基础——Shell概述和入门(一)
66 0
Linux下的Shell基础——Shell概述和入门(一)
|
6月前
|
Shell 索引
shell脚本入门到实战(四)- 数组
shell脚本入门到实战(四)- 数组
|
6月前
|
Shell
shell脚本入门到实战(三) - 变量
shell脚本入门到实战(三) - 变量
|
3月前
|
分布式计算 资源调度 Hadoop
Hadoop入门基础(五):Hadoop 常用 Shell 命令一网打尽,提升你的大数据技能!
Hadoop入门基础(五):Hadoop 常用 Shell 命令一网打尽,提升你的大数据技能!
|
3月前
|
Java Shell Linux
【Linux入门技巧】新员工必看:用Shell脚本轻松解析应用服务日志
关于如何使用Shell脚本来解析Linux系统中的应用服务日志,提供了脚本实现的详细步骤和技巧,以及一些Shell编程的技能扩展。
55 0
【Linux入门技巧】新员工必看:用Shell脚本轻松解析应用服务日志
|
5月前
|
网络协议 Linux Shell
基础入门-反弹SHELL&不回显带外&正反向连接&防火墙出入站&文件下载
基础入门-反弹SHELL&不回显带外&正反向连接&防火墙出入站&文件下载
|
6月前
|
监控 关系型数据库 Shell
Shell脚本入门:从基础到实践,轻松掌握Shell编程
Shell脚本入门:从基础到实践,轻松掌握Shell编程
131 3
|
6月前
|
存储 Shell C语言
shell脚本 编程 变量 基本入门(详解)
shell脚本 编程 变量 基本入门(详解)