shell脚本基础

2023-05-16

摘自:一篇教会你写90%的shell脚本

1.注释:

        单行注释:#

        多行注释: (注意第一种注释方法的 “:"后面有一个空格)

: '
多行注释内容
'

<<block
多行注释内容
block

2.变量:局部变量,环境变量(全局变量),shell变量有环境变量也有局部变量。

3.变量操作:

#创建普通变量:name="test"            #等号两边不允许有空格
#创建局部变量:local name="test" 
#创建只读变量:readonly name ="test"  #只读不可被修改、删除
#变量重定义:name="new test"
#使用变量:$name 或 ${name}           #eg:echo ${name}
#删除变量:unset name

 4.字符串变量

#!/bin/bash
#----1).单引号:定义无效变量,且引号之间不允许有单独的单引号
#    下述代码输出结果为:hello $name
name="Hello"
echo 'hello $name'

#----2).双引号:定义有效变量,
#    下述代码输出结果为:hello Hello
echo "hello $name" 

#----3).拼接字符串
#    下述代码输出结果均为:Hello123456
ID="123456"
str=$name$ID

name="Hello""123456"

name='Hello''123456'

#-----4).获取字符串长度,使用 # 获取长度
#    下述代码输出结果为:11
echo ${#name}

#-----5).提取子字符串,${str:m:n} 截取str的从第m个字符开始的n个字符  M不写则默认为0
#    下述代码输出结果为:12
echo ${name:5:2}

 5.数组(bash仅支持一维数组)

#!/bin/bash

#------1).定义数组:小括号做边界、空格做元素分割
array_name=(dao ke dao fei chang dao)

#------2).对数组某个变量赋值
array_name[0]="daode"

#------3).输出数组单个元素      输出:daode
echo ${array_name[0]}

#------4).输出数组所有元素      输出:daode ke dao fei chang dao
echo ${array_name[@]}

#------5).获取数组中元素个数    输出:6
echo ${#array_name[@]}
echo ${#array_name[*]}

#------6).获取单个元素长度      输出:3 5
echo ${#array_name[3]}
echo ${#array_name}            #这里相当于获取数组首个元素的长度

 6.参数传递

#!/bin/bash

#获取命令行中的参数以用来计算
#我们以命令行输入:  ./test.sh A=8 B=10 为例
str0=$0         #一般为:"./test,.sh" 当bash执行时为:"test.sh"
str1=$1         #获取指令的第1个参数:A=8
str2=$2         #获取指令的第2个参数:B=10
a=${str1:2:2}   #截取参数中的值:8
b=${str2:2:2}   #截取参数中的值:10

((sum=a+b))

echo "执行的文件是:$0"         #输出结果:./test.sh
echo "第一个参数:$1"           #输出第一个参数:A=8
echo "第二个参数:$2"           #输出第二个参数:B=10
echo "参数个数:$#"             #传入的参数个数
echo "A+B=$sum"
echo "当前脚本进程号:$$"               #当前运行的脚本的进程号
echo "后台最后一个脚本进程号:$!"       #后台运行的最后一个进程的ID
echo "显示脚本是否正常退出:$?"         #显示最后命令是否正常推出 0表示正常
echo "*********************************"
# $* :以字符串形式传递参数,每个参数都是独立的元素
for var in $*
do
        echo ${var}
done
echo "-----------------------------"
# $@ :以字符串形式传递参数,每个参数都是独立的元素
for var in $@
do
        echo ${var}
done
echo "-----------------------------"
# "$*" :将所有参数作为一个参数传递,
for var in "$*"
do
        echo ${var}
done
echo "-----------------------------"
# "$@" :以字符串形式传递参数,每个参数仍旧相对独立
for var in "$@"
do
        echo ${var}
done
echo "********************************"

7.七种数学计算方式

(1) 使用let命令进行算术运算,只支持整数运算。
(2) 使用expr命令进行算术运算,只支持整数运算。他的算式每个元素之间需要加空格
(3) 使用运算语法:$[算术表达式],只支持整数运算。
(4) 使用运算语法:$((算术表达式)),只支持整数运算。常用。
(5) 在初始化变量时declare -i,将变量定义为"整数"类型,则可直接进行整数运算。
(6) 使用bc命令进行算术运算,支持整数和小数运算。
(7) 使用awk命令进行算数运算,支持整数和小数运算。

#!/bin/bash

a=10
b=15
#-----1). (())  最常用的效率也高的
((sum=a+b*54-8))        #符号内进行基本运算,变量名前不加$,
sum=$((a+b+32))         #通过 $ 符号直接传递计算结果
sum=$((a>b && b>=0))    #做一些逻辑运算,可用于if、while等判断语句
((sum1=a+b,sum2=a-b))   #通过 ,分割并计算多个表达式
sum=$((a+b,a/b))        #这种情况,会以最后一个表达式的结果作为输出结果
sum=$((--a))            #可以做自减、自增计算

#-----2). let   与(())用法类似
let sum1=a+b sum2=a*b   #与(())不同,这里用 空格 分割多个计算式

#-----3). $[]   与(())用法类似
sum=$[u=a+b,u2=a-b]     #同(())一样,都是用 空格 分割多个计算式

#-----4). expr  也可处理字符串。
#       在shell脚本中要用 ` 符号括起来,ESC键下面那个键。
#       语句中每一项都需 空格 隔开。
sum=`expr 10 \* 5`                      #做乘法运算时*前要加/

#-----5). bc    用于整数和小数
#       基本格式:echo "expression" | bc
#       表达式默认用双引号括起来,用单引号变量会被当作字符处理。
echo "10^2+sqrt(5)"|bc                  #直接输出结果
sum=$(echo "15+5" | bc)                 #通过 $ 传递输出结果
sum=$(echo "scale=2;($a+1)/3"|bc)       #scale 定义保留几位小数
sum=$(echo "ibase=16;AA" |bc)           #进制转换,这里将16进制转换为10进制
sum=$(echo "obase=16;255" |bc)          #进制转换,将十进制转换为16进制

#-----6). declare -i    直接将变量声明为整数,然后直接进行“算数计算”
declare -i s            #声明 s 为证整数型变量,可直接进行运算
s=$a+$b
declare +i s            #取消声明。

#-----7).awk    是一个强大的文本的分析工具,少用于计算
sum=$(awk 'BEGIN{print '$b'+3 }')               #算数运算,变量加单引号
sum=$(awk 'BEGIN{print ('$a'+1)/3}')            #没设置保留小数位
sum=$(awk 'BEGIN{printf "%.9f\n",'$b'/9}')      #printf 设置保留的小数位

8.算术运算符

#!/bin/bash

a=8
b=6
#算术运算符简单例子
s0=$((a+b-b*a+a/b-a%b))
s1=$((a**b))
s2=$((a<=b))
s3=$((a|=(1<<b)))
s4=$((!(a>b && a<0)))
s5=$((--b))
echo "$s0,$s1,$s2,$s3,$s4,$s5"

9.关系运算符(仅支持数字,用于条件判断语句)

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

#!/bin/bash

a=10
b=8
if [ $a -eq $b ] #中括号两边和运算符两边都需要添加空格
then
        echo "YES"
else
        echo "NO"
fi

10.字符串运算符(用于条件判断语句)

= :检测两个字符串是否相等         [ $str1 = $str2 ] 
!= :检测两个字符串是否相等        [ $str1 != $str2 ] 
-z :检测字符串长度是否为0          [ -z $str1 ] 
-n :检测字符串长度是否为0          [ -n "$str2" ] 
$  :检测字符串是否为空                 [ $str1 ] 

11.布尔运算符(用于条件判断语句)

!   :非运算,!true即为false
-o :或运算,多个判定条件一个为true,则结果为true         [ $a -lt 20 -o $b -gt 100 ]
-a :与运算, 多个判定条件一个为false,则结果为false     [ $a -lt 20 -a $b -gt 100 ] 

12.逻辑运算符 (用于条件判断语句)与布尔运算符的不同在于需要双中括号。

&&  :逻辑的 AND       [[ $a -lt 100 && $b -gt 100 ]] 

||     :逻辑的 OR         [[ $a -lt 100 || $b -gt 100 ]] 

13.文件测试运算符

 14.命令替换(即将命令执行的结果传递给某个变量)

两种方式: `命令`$(命令)

两种命令效果相同但是,$()可以嵌套使用。

#!/bin/bash

s0=$((3+4))
s1=`ls /home`
s2=$(date)
sleep 10s
s3=$(echo "北京时间为: $(date)")

echo $s0
echo $s3
echo $s2
echo $s1

15.逻辑判断中符号注意事项

  1. [ ] : 中括号旁边和运算符两边必须添加空格 (可以使用,不推荐)
  2. [[ ]]:中括号旁边和运算符两边必须添加空格 (字符串验证时,推荐使用)
  3. (()) : 中括号旁边和运算符两边必须添加空格 (数字验证时,推荐使用)
  4. [[]] 和 (()) 分别是[ ]的针对数学比较表达式和字符串表达式的加强版。

注:-o、-a可以直接在 [] 结构中正常运行。但是 || 、&&则必须在 [[]] 或 (()) 中运行。 

16.echo 和 printf

echo:仅用于字符串的输出,没有使用printf的移植性好

printf:不会自动换行、需要添加 '\n'。eg:printf "%-10s=%d\n" 3+5^2 $((3+5**2))。

       格式符:
                %s  :对应位置的参数 以字符串格式输出
                %c  :对应位置的参数 以字符格式输出
                %d  :对应位置的参数 以十进制整数输出
                %f   :对应位置的参数 以十进制数输出
                %b  :对应位置的参数用引号括起来时会识别其中的转义符。

        %-10s : 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。

        %-4.2f :指格式化为小数,宽度为4个字符,其中.2指保留2位小数。

        转义符:
            \a        :警告字符,通常为ASCII的BEL字符
            \b        :后退
            \c        :%b格式替换的内容中含有\c时,\c后的内容会被忽略。见下附代码:
            \f         :换页(formfeed)
            \n        :换行
            \r         :回车(Carriage return)
            \t         :水平制表符
            \v        :垂直制表符
            \          :一个字面上的反斜杠字符
            \ddd    :表示1到3位数八进制值的字符。仅在格式字符串中有效
            \0ddd  :表示1到3位的八进制值字符

                

#!/bin/bash

printf "%-10s=%d %b aa\n" test $((3+5**2)) "He\cllo"
: '输出结果:
test      =28 He    #注意:输出内容没有进行换行
'

17.流程控制 (cmd指操作,可以有多个操作)

        1).if的使用。与其他语言不同,sh中操作不可为空,即cmd部分不可为空。格式如下:

-----------------------------------------
:'if:
if condition
then
    cmd
fi
'
---------------------------------------
:'if else:
if condition
then
    cmd
else
    cmd
fi
'
----------------------------------------
:'if else-if else:
if condition
then
    cmd
elif condition
then
    cmd
else
    cmd
fi
'

        2).for的使用:

 注:当for的列表值中有 引号 存在时需要用双引号括起来或用反斜线 \ 转义

for var in item1 item2 ... itemN (或((i<0;i<10;i++))这种格式)
do
    cmd
done

        3).while的使用

while condition
do
    cmd
done

        4).until循环的使用

until condition
do
    command
done

         5).case多分支结构的使用:

case $关键字 in
关键字1)
    cmd;;
关键字2)
    cmd;;
*)
    echo "error!";;    
esac

        6).无限循环

while :        (或写成 while true)
do
    command
done

for (( ; ; ))

        7).跳出循环:

break:允许跳出高一级的循环

continue:仅跳出当前

#!/bin/bash

j=0
while :
do
        ((j++))
        echo -n "$j a "

        if ((j>5 && j<8))
        then
                echo "b"
                continue
                echo "?"
        fi

        if ((j>10))
        then
                echo "over"
                break
                echo "!"
        fi

        echo "c"
done

18.自定义函数

        注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

function name    #或者是: name() 这种格式
{
    action
    return int                    #return返回值的范围:0-255一般用作返回状态码,不加return则会将最后一条命令执行状态作为返回值0:执行成功。返回值可通过 $? 获取。
}

#!/bin/bash

fun()
{
	local sum=$(($1+$2))
	return $sum
}
fun 3 4
echo $?    #显示的是fun函数的返回值
echo $?    #则为上一条语句即“echo $?"的执行状态

function fun
{
	str=$1
	local sum=${#str}
	echo $sum
}
result=$(fun hello)   #类似于这种获取函数返回值需要使用echo 或 ptintf
echo $result

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

shell脚本基础 的相关文章

  • 如何在bash中仅提取两个字符串之间多行的第一个实例?

    我的文件是 abc 123 xyz abc 675 xyz 我想提取 abc 123 xyz 123 可以是任何东西 重点是我想要第一次出现 我尝试使用这个 sed n abc xyz p filename 但这给了我所有的例子 我怎样才能
  • 从 bash 脚本运行节点

    很简单 我正在尝试使用 cron 自动运行 nodejs 脚本 但是脚本本身似乎无法运行该文件 我的脚本很简单 usr bin env node node var node assets js update js 但是 在运行此命令时 它返
  • linux下如何获取昨天和前天?

    我想在变量中获取 sysdate 1 和 sysdate 2 并回显它 我正在使用下面的查询 它将今天的日期作为输出 bin bash tm date Y d m echo tm 如何获取昨天和前天的日期 这是另一种方法 对于昨天来说 da
  • Bash 脚本 - 迭代 find 的输出

    我有一个 bash 脚本 其中需要迭代 find 命令输出的每一行 但似乎我正在迭代 find 命令中的每个单词 以空格分隔 到目前为止我的脚本看起来像这样 folders find maxdepth 1 type d for i in f
  • 如何从 Linux 的 shell 中删除所有以 ._ 开头的文件?

    确实如标题所示 我已将许多文件从 Mac 复制到 Raspberry Pi 这导致了许多以前缀开头的多余文件 我想删除以以下开头的文件夹中的每个文件 我该怎么做 尝试类似的方法 cd path to directory rm rf 或者 如
  • 在 shell 脚本中查找和替换

    是否可以使用 shell 在文件中搜索然后替换值 当我安装服务时 我希望能够在配置文件中搜索变量 然后在该值中替换 插入我自己的设置 当然 您可以使用 sed 或 awk 来完成此操作 sed 示例 sed i s Andrew James
  • 如何使用AWK脚本检查表的所有列数据类型? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 在这里 我正在检查表中第一列的数据类型 但我想知道AWK中表的所有列数据类型 我尝试过 但只能获得一列数据类型 例如 Column 1
  • 如何让“grep”从文件中读取模式?

    假设有一个很大的文本文件 我只想打印与某些模式不匹配的行 显然 我可以使用egrep v patter1 pattern2 pattern3 现在 如果所有这些模式都在一个文本文件中怎么办 最好的制作方法是什么egrep从文件中读取模式 g
  • Bash 脚本大小限制?

    我有一个 bash 脚本 在 RHEL 或 OS X 上运行时出现以下错误 第 62484 行 意外标记 换行符 附近出现语法错误 第 62484 行 o gz 这是一个自动生成的脚本 用于解决我公司使用的 Grid Engine 计算集群
  • 如何将设备屏幕位置转换为发送事件位置?

    我知道关于input tap x yshell 命令 但是 我想了解如何 使用执行单击sendevent命令 我能够通过以下命令实现它 sendevent dev input event5 3 53 X sendevent dev inpu
  • 在 bash 中使用单个命令为 shell 变量分配默认值

    我对 bash 3 00 shell 脚本中的变量进行了大量测试 如果未设置变量 则它会分配默认值 例如 if z VARIABLE then FOO default else FOO VARIABLE fi 我似乎记得有一些语法可以在一行
  • shell脚本中的\r字符

    我在尝试执行 shell 脚本时收到以下错误 r command not found line 2 请提出同样的解决方案 以下是脚本中使用的初始行 bin sh if lt 1 then echo ERROR Environment arg
  • if [ -z "${FILE_LIST}" ] 中的 -z 是什么

    遇到了这个 什么是 z在 shell 脚本中if z FILE LIST 是相同的test And man test gives z STRING the length of STRING is zero 注意 在某些平台上 是一个符号链接
  • 添加要在给定命令中运行的 .env 变量

    我有一个 env 文件 其中包含如下变量 HELLO world SOMETHING nothing 前几天我发现了这个很棒的脚本 它将这些变量放入当前会话中 所以当我运行这样的东西时 cat env grep v xargs node t
  • 如何在 Windows 下向 .sh 脚本传递参数?

    我正在尝试在 Windows 下执行 sh 脚本 我安装了 Git 它允许我执行 sh 文件 但是 如果不使用 sh 作为执行前缀 我似乎无法传递任何参数 我的 sh 文件 echo Test 1 如果我用以下命令执行它 gt sh tes
  • 如何在shell中输出返回码?

    我正在尝试通过调用自定义 shell 脚本sh bin sh c myscript sh gt log txt 2 gt 1 echo 该命令的输出是创建的后台进程的 PID 我想指导 bin sh保存返回码myscript sh到某个文件
  • 如何通过保持目录结构完整来同步路径中匹配模式的文件?

    我想将所有文件从服务器 A 复制到服务器 B 这些文件在不同级别的文件系统层次结构中具有相同的父目录名称 例如 var lib data sub1 sub2 commonname filetobecopied foo var lib dat
  • 分叉/多线程进程|重击

    我想让我的代码的一部分更加高效 我正在考虑让它分叉成多个进程 并让它们一次执行 50 100 次 而不是只执行一次 例如 伪 for line in file do foo foo2 foo3 done 我希望这个 for 循环运行多次 我
  • 通过 sed 使用 unix 变量将数据附加到每行末尾[重复]

    这个问题在这里已经有答案了 我有一个文件 我想使用 SED 将值附加到每行末尾的 unix 变量中 我已经通过 AWK 实现了这一点 但我想在 SED 中实现 像这样的东西 我已经尝试过以下命令 但它不起作用 sed i s BATCH R
  • 符合 POSIX 标准的 shell 相当于 Bash“while read -d $'\0' ...”?

    我正在尝试使 Bash 脚本严格符合 POSIX 标准 即消除任何潜在的 Bashisms http mywiki wooledge org Bashism 通过使用checkbashisms px script filename 在给定的

随机推荐