shell基本语法

shell初识



shell介绍

shell是一个用c语言编写的应用程序,是用来和linux内核打交道的。比如我们在终端输入ls,那么shell就会帮我们把命令翻译成内核可以识别的指令,从而访问内核所提供的服务。

shell脚本

shell脚本指的是shell可以识别的脚本程序。shell和shell脚本之间的关系就类似于python解释器和py文件之间关系一样,一个是脚本解释器,一个是脚本。只不过为了方便,我们把shell就当成shell脚本了,但实际上shell和shell脚本是两码事。

shell环境

Shell 编程跟 java、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,我们只需要知道两个即可:
    Bourne Shell,也就是我们一般会在shell脚本的第一行写上#!/bin/sh
    Bourne Again Shell,也就是我们一般会在shell脚本的第一行写上#!/bin/bash

这两种方式一般区分的不是特别明显,因此些#!/bin/sh或者#!/bin/bash都行。
但是真要说区别的话,这两者之间有什么区别呢?

对于#!/bin/sh来说,如果中间的代码出现了错误,那么后面的代码不会执行。
但如果是#!/bin/bash的话,中间代码出现了错误,后面的代码仍然会执行

为什么会出现这样的错误呢?
因为sh一般设成bash的软链,在一般的linux系统中,使用#!/bin/sh相当于#!/bin/bash --posix
所以,sh跟bash的区别,实际上就是bash有没有开启posix模式的区别

所以,可以预想的是,如果第一行写成 #!/bin/bash --posix,那么脚本执行效果跟#!/bin/sh是一样的

第一个shell脚本

我们来写一个shell脚本吧,当然啦,必须是hello world

#!/bin/sh
echo hello world
echo "hello world"

# 解释一下,第一行表示我们指定的shell解释器,注意如果没有这一行,会使用默认的解释器
# 但是一般情况下,我们会指定为#!/bin/sh 或者#!/bin/bash
# 第二行和第三行表示输入hello world,区别就是没有加上双引号,这里加与不加均可,但是一般我们都加上。
# 这里的#表示注释,echo类似于python中的print。

shell脚本以.sh结尾,直接执行即可。但是可能会报错,显示没有权限,这时候通过chmod 755 xx.sh赋予权限即可执行。

1229382-20190728204307074-2049862626.png



shell变量


定义和使用变量

变量的定义规则和平常的编程语言是一样的,使用字母数字下划线,并且开头不能是数字。
但是需要注意的一点是:等号之间不能有空格,比如在python中,定义一个变量可以是name = "satori",并且pep8建议等号之间要空格,看起来更工整,但是shell脚本里面这么定义是不可以的,等号之间不可以有空格,因此要这么定义name="satori"
#!/bin/sh
name="mashiro"
age=16

# 如何打印变量呢?通过$变量名 的方式
echo "name is $name,age is ${age}"
# 但是注意到我们在打印age的时候加上了{}
# 其实加不加都无所谓的,但是我们最好还是加上
# 为什么呢?比如说$nameaaa,这里我想打印name在连接上aaa,但如果这样的话会把nameaaa当成一个整体
# 而这个变量显然没有被定义,因此如果我们加上{}就不会出现这个问题了。${name}aaa,就会输出mashiroaaa
# 这里name后面是逗号,所以没事

1229382-20190728204313888-1685723989.png

对于一些整型、字符型的变量,就不用说了。我们还可以嵌入一些命令`

#!/bin/sh

echo "下面我要创建文件了"
# 创建一个文件,shell会逐行执行,执行到这里会创建一个文件。
# 在哪里创建呢?会在当前shell脚本所在的目录里面创建
# 在终端里面执行的命令是可以直接放到shell里面来的
touch "fuck_shanshan.txt"

# 给一个变量赋值,我们也可以将命令执行的结果赋值给一个变量
# 注意到pwd会打印当前的工作区,所以我们这里是``,表示执行原生的命令,将命令的结果赋值给work_dir
# 如果是"pwd",那么表示将pwd这三个字符赋值给work_dir
work_dir=`pwd`
echo "我当前的工作区是:${work_dir}"

1229382-20190728204320791-1354714642.png


只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

#!/bin/bash 

v="哈哈哈"
readonly v  # 设置为只读变量
echo "${v}"  # 可以访问

v="咯咯咯"  # 尝试修改 

1229382-20190728204327770-2130335021.png


删除变量

使用 unset 命令可以删除变量,直接unset 变量名 即可,但是unset不能删除只读变量

1229382-20190728204337109-677888063.png


变量类型

运行shell时,会同时存在三种变量:

  • 1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
  • 2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
  • 3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

Shell 字符串

字符串是shell编程中最常用的数据类型(话说除了数字和字符串,也没啥其他类型好用了),字符串可以使用单引号、也可以使用双引号,也可以不使用引号,一般我们使用双引号即可。
  • 拼接字符串

    #!/bin/bash
    name="古明地觉"
    where="东方地灵殿"
    # 多个字符串直接拼接即可之间
    # "a""b""c"  --> abc
    echo "${name}""来自于""${where}"

    1229382-20190728204346310-763879262.png

  • 获取字符串长度

    使用#即可

    #!/bin/bash
    name="古明地觉"
    echo "${#name}"

    1229382-20190728204353536-283588286.png

    也可以看出,这里是用字符来计算的,不是用字节来计算的。

  • 提取子字符串

    #!/bin/sh
    
    string="helloworld"
    echo "${string:1}"
    echo "${string:1:4}"

    1229382-20190728204402119-81563040.png

    变量后面加上:,即可提取子字符串,string:1:4表示从索引为1的位置开始取,取4个,注意shell里面所以也是从0开始的。如果是string:1的话,那么会从索引为1的位置取到结尾

    #!/bin/sh
    
    string="helloworld"
    echo "这个会输出啥嘞,${string:100}"  # 这里表示从索引为100的位置取到结尾
    echo "${string:1:100}"  # 从索引为1的位置开始,取100字符

    1229382-20190728204409711-1570208734.png

  • 字符串的截取(补充)

    #号截取,删除左边字符,保留右边字符。

    var="http://www.bilibili.//com"
    echo "${var#*//}"  
    # var表示的是变量,#是运算符,表示删除var中右边的字符,*//表示以第一个//结尾的任意字符
    
    # 所以结果是www.bilibili.//com

    ##号截取,删除左边字符,保留右边字符

    var="http://www.bilibili.//com"
    echo "${var##*//}" 
    # 和#的区别就是,##类似于正则中的贪婪模式,如果是##,那么*//表示最后一个以//结尾的任意字符
    # 所以结果是com

    %号截取,删除右边字符,保留左边字符

    var="http://www.bilibili.//com"
    echo "${var%//*}"   
    # 和#正好相反,删除右边的字符,以//开头的任意字符
    # 所以结果是http://www.bilibili.

    %% 号截取,删除右边字符,保留左边字符

    var="http://www.bilibili.//com"
    echo "${var%%//*}" 
    # 不用我说了
    # 结果是http:

    从左边第几个字符开始,及字符的个数

    var="http://www.bilibili.//com"
    echo "${var:0:6}"
    # http:/

    从左边第几个字符开始,一直到结束。

    var="http://www.bilibili.//com"
    echo "${var:6}"
    # /www.bilibili.//com

    从右边第几个字符开始,及字符的个数

    var="http://www.bilibili.//com"
    echo ${var:0-7:3}
    # 其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。
    # 输出结果是i./

    从右边第几个字符开始,一直到结束。

    var="http://www.bilibili.//com"
    echo ${var:0-7}
    # i.//com

shell注释

开始就已经提过了
以 # 开头的行就是注释,会被解释器忽略。但这是单行注释,此外还有多行注释

:<<EOF
注释内容...
注释内容...
注释内容...
EOF

EOF 也可以使用其他符号:

:<<'
注释内容...
注释内容...
注释内容...
'

:<<!
注释内容...
注释内容...
注释内容...
!


shell脚本传递参数

我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
类似于python里面的sys.argv,sys.argv[0]表示文件名,sys.argv[1]表示第一个参数。。。。依次类推
#!/bin/sh
name="$1"
age="$2"
gender="$3"

echo "name is ${name},age is ${age},gender is ${gender}"

1229382-20190728204559557-1333408071.png

可以看到$0 $1 $2等等都是系统的保留变量,那么除此之外,还有哪些保留的变量呢?
  • $#:传递到脚本的参数个数
  • $*:显示向脚本传递的所有参数
  • $@:显示向脚本传递的所有参数,这个和$*有什么区别呢?后面举例说明
  • $$:脚本运行的当前进程的id号
  • $!:后台运行的最后一个进程的id号
  • $?:显示最后命令的退出状态,如果没有错误则为0,其他的值表示有错误
#!/bin/bash

echo "shell传递参数实例"
echo "一共传过来$#个参数"
echo "第一个参数为$0"  # 如果我们设置了 xx="$0",那么这里要写${xx},如果直接写的话,直接$0即可,切记不可以这么写:${$0}
echo "传递到所有脚本的所有参数是:$*"
echo "传递到所有脚本的所有参数是:$@"
echo "脚本运行的当前进程的id号是:$$"
echo "后台运行的最后一个进程的id号是:$!"
echo "程序的退出状态,0是正常退出哦。状态为:$?"

1229382-20190728204607812-1037364753.png

那么$*和$@到底有神马区别,假设我们传递了1 2 3 4 5这五个参数,那么$*的话,等价于"1 2 3 4 5"(传递了一个参数),$@等价于传递了"1""2""3""4""5"(传递了五个参数)

我们不妨检测一下,这里使用了for循环,我们后面会介绍

#!/bin/bash

echo "--\$*演示--"  # \表示转义字符
for i in "$*";do
  echo "${i}"
done

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

1229382-20190728204614881-1176775332.png



shell数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。

定义数组

在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为,数组名=(值1 值2 ... 值n)

例如array_name=(value0 value1 value2 value3)
array_name=(
value0
value1
value2
value3
)

读取数组

读取数组元素值的一般格式是:${数组名[下标]}
例如:value=${array_name[n]}
使用 @ 符号可以获取数组中的所有元素,例如:echo ${array_name[@]}
#!/bin/sh
arr=("mashiro" 16 "东方地灵殿")
echo "${arr[0]}今年${arr[1]}岁,来自于${arr[2]}"
echo "直接打印所有内容:${arr[@]}"

1229382-20190728204624698-2056025751.png

获取数组的长度

获取数组长度的方法与获取字符串长度的方法相同,例如:

#!/bin/sh
arr=(1 2 3 4 5)
# 获取数组元素的个数,这里加上了[@]
echo "${#arr[@]}"  # 或者${#arr[*]}也是一样的

# 如果没有[@]
echo "${#arr}"
# 直接输出数组
echo "${arr}"

1229382-20190728204630924-1196987520.png



shell运算符


算数运算符

bash不支持原生的数学运算,但是我们可以通过expr来实现
#!/bin/bash

val=`expr 2 + 2`  # 表示计算2+2的值,注意+两边要有空格,而且这里是反引号,expr 表示计算后面的值
echo "${val}"

a=10
b=20
val=`expr ${a} + ${b}`
echo "${val}"

# 如果+两边没有空格
val=`expr 2+2`
echo "${val}"

val=`expr ${a}+${b}`
echo "${val}"

1229382-20190728204645256-2065330260.png

#!/bin/bash
a=10
b=20

val=`expr $a + $b`
echo "a+b=${val}"

val=`expr $a - $b`
echo "a-b=${val}"

val=`expr $a \* $b`  # 注意:如果是乘法,那么*前面要加上\
echo "a*b=${val}"

val=`expr $a / $b`
echo "a/b=${val}"

val=`expr $a % $b`
echo "a%b=${val}"

val=`expr $a == $b`
echo "a==b=${val}"

val=`expr $a != $b`
echo "a!=b=${val}"

1229382-20190728204652393-1305616740.png


关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。假设a=10,b=20

  • -eq:检测两个数是否相等。[ $a -eq $b ] 返回 false。
  • -ne:检测两个数是否不相等。[ $a -ne $b ] 返回 true。
  • -gt:检测左边的数是否大于右边的数。[ $a -gt $b ] 返回 false。
  • -lt:检测左边的数是否小于右边的数。[ $a -lt $b ] 返回 true。
  • -ge:检测左边的数是否大于等于右边的数。[ $a -ge $b ] 返回 false。
  • -le:检测左边的数是否小于等于右边的数。[ $a -le $b ] 返回 true。

这个代码示例,在流程控制中会介绍


布尔运算符

假设a=10,b=20

  • !:非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。
  • -o:或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ] 返回 true。
  • -a:与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ] 返回 false。

逻辑运算符(可以不用看)

假设a=10,b=20

  • &&:逻辑的 AND,[[ $a -lt 100 && $b -gt 100 ]] 返回 false
  • ||:逻辑的 OR,[[ $a -lt 100 || $b -gt 100 ]] 返回 true

字符串运算符

假定变量 a 为 "abc",变量 b 为 "efg"

  • =:检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。
  • !=:检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回 true。
  • -z:检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。
  • -n:检测字符串长度是否为0,不为0返回 true。[ -n "$a" ] 返回 true。
  • $:检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。

文件测试运算符

file="/root/sh/1.sh"

-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。

注意:凡是没有用代码举例的运算符,一般都是放在if else语句里面的,后面会说。这里想说的是,这些条件都是放在[]里面的,关键是[ ]前后要和代码有一个空格,这是必须的。也就是我们的条件是判断a和b是否相等,要这么写[ $a -eq $b ],不可以这么写,[$a -eq $b], 内容不能和[]两边挨着



shell echo命令

很早之前就介绍过了,这里再复习一遍

显示普通字符串

#!/bin/sh
echo "my name is mashiro"
echo my name is mashiro  # 这里的""可以省略

1229382-20190728204701961-1095310320.png

显示转义字符

#!/bin/bash
echo "\"my name is mashiro\""
echo \"my name is mashiro\"  # 同理""也可以省略

1229382-20190728204708840-658777251.png

显示变量

#!/bin/sh
read name  # read name 表示从命令行读取,然后将值赋值给name

echo "my name is ${name}"

1229382-20190728204717109-1960294238.png

同理read也可以接收多个变量

#!/bin/sh
read name age gender
echo "$name $age $gender"

1229382-20190728204731712-1483123185.png



shell printf命令

printf 命令模仿 C 程序库(library)里的 printf() 程序。

printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。

printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。
#!/bin/bash
echo "hello world"
printf "hello world\n"

1229382-20190728204739325-887864316.png

#!/bin/sh
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876

1229382-20190728204746191-1636650435.png



shell 流程控制


if else

注意在shell里面,如果不需要else,那么就不要写。如果是其它编程语言的话,可以加上else不写逻辑,但是shell不行

if语法格式

if condition
then
    command1 
    command2
    ...
    commandN 
fi

也可以写成一行,但是要加上; if condition;then command;fi
末尾的fi就是if倒过来拼写,后面还会遇到类似的。

if else 语法格式

if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi


if else-if else 语法格式

if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi
#!/bin/sh

read age gender

# 注意这里可不要写成 $age >= 18,这是不行的。
# 对于是否相等,则既可以用$age == 18和$age -eq 18
# 而且字符串要用=来判断,注意是=,不是==
if [ $age -ge 18 -a $gender = "f" ]
then
  echo "perhaps we can make a deal"
else
  echo "不约"
fi

1229382-20190728204756602-281676642.png

#!/bin/sh

read age gender

if [ $age -ge 18 -o $gender = "f" ]
then
  echo "perhaps we can make a deal"
else
  echo "不约"
fi

1229382-20190728204804716-906690269.png

#!/bin/bash

a=10
b=10

if [ $a == $b ]
then
  echo "a和b是相等的"
fi

if [ $a -eq $b ]
then
  echo "a和b是相等的"
fi

1229382-20190728204812006-1215637331.png

#!/bin/bash

read a b 

if [ $a -gt $b ]
then
  echo "a是大于b的"
elif [ $a -lt $b ]
then 
  echo "a是小于b的"
else
  echo "a是等于b的"
fi

1229382-20190728204821126-1828589236.png


for循环

for循环一般格式为:

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

写成一行:for var in item1 item2 ... itemN; do command1; command2…; done;

in列表是可选的,如果不用它,for循环使用命令行的位置参数。
#!/bin/bash

for v in 1 2 3 4 5
do
  echo "val=${v}"
done

arr=("a" "b" "c" "d")
for v in ${arr[@]}  # 遍历数组,记得加上[@],否则只打印第一个元素
do
  echo "val=${v}"
done

1229382-20190728204828464-1307215783.png


while 语句

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

while condition
do
    command
done
#!/bin/sh
num=1
while [ $num -lt 5 ]  # 当num小于5的时候
do
    echo "num=$num"
    let "num++"  # let可以执行表达式,让变量计算不需要加上$
done

1229382-20190728204836492-463544620.png


break和contiune

break结束当前循环,continue继续下一层循环

#!/bin/bash

echo "输入一个可以执行的文件"
while read file
do
  if [ -x ${file} ]
  then
    echo "文件为${file},这是一个可以执行的文件,循环结束"
    break
  else
    echo "文件为${file},这不是一个可以执行的文件,请重新输入"
    continue
  fi
done

1229382-20190728204843070-707451859.png


until 循环

until 循环执行一系列命令直至条件为 true 时停止。

until 循环与 while 循环在处理方式上刚好相反。

一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。

until condition
do
    command
done
#!/bin/bash
a=1
until [ ! $a -le 10 ]  # !表示取反
do
  echo "a=${a}"
  let "a++"
  a=`expr ${a} + 1`  # 除了let "a++"还可这么写
done

1229382-20190728204850549-1176354387.png


case

Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:
case 值 in
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac
#!/bin/bash

echo "请输入abcde五个字符中的一个"
read alpha

case ${alpha} in
  a) echo "你选择了a"
  ;;
  b) echo "你选择了b"
  ;;
  c) echo "你选择了c"
  ;;
  d) echo "你选择了d"
  ;;
  e) echo "你选择了e"
  ;;
  *) echo "不在abcde当中"
  ;;
esac

1229382-20190728204911886-366473494.png

shell的case语句设计的很有个性



shell 函数


定义函数

linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。
shell中函数的定义格式如下:

funcName(){
    函数体
}
#!/bin/bash

mashiro(){
  echo "i'm mashiro"
}

echo "调用函数啦"
mashiro  # 调用函数不用加括号
echo "函数调用完毕"

1229382-20190728204919242-2050887158.png


函数的返回值

#!/bin/bash
add(){
  echo "输入两个数字:"
  read a b
  return `expr $a + $b`
}
add
num=$?  # 函数的返回值,在调用完函数之和,通过$?获取。并且要马上获取,如果获取之前插入了别的命令,就获取不到了,只能获取到0。并且函数只能返回整型
echo "输入的两个数字之和为:${num}" 
if [ $num -gt 10 ]
then
  echo "两个数字之和大于10"
else
  echo "两个数字之和小于等于10"
fi

1229382-20190728204926726-701047472.png


函数参数

shell中怎么给传递参数呢?还记得之前的向shell脚本传递参数的$1 $2...$n吗?
#!/bin/sh

func(){
  echo "函数的第一个参数是:$1"
  echo "函数的第二个参数是:$2"
  echo "函数的第三个参数是:$3"
  echo "函数的第四个参数是:$4"
}

func 1 2 3 4   # 直接在函数名后面传递参数即可,注意如果函数的参数超过了十个,那么从第十个开始要通过${10}这样的方式获取,要加上{}
# 函数参数的获取是从1开始的,第一个参数就是$1

1229382-20190728204933915-239292940.png



shell 引用文件

和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。
引用方式,通过.来引用,直接. xxx.sh文件路径 即可,注意.和shell脚本之间要有空格

比如我们写了一个fuck.sh,那么在相同目录下创建的test.sh要想引用的话,就可以通过. ./fuck.sh来引用。第一个.表示引用,第二个.则是表示引用的文件的所在目录

/root/fuck.sh

#!/bin/bash
url="http://www.bilibili.com"

/root/sh/test.sh

#!/bin/bash
. ../fuck.sh
echo "${url}"

1229382-20190728204940684-552834915.png

转载于:https://www.cnblogs.com/traditional/p/11260842.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值