【Linux篇】Shell脚本语法

news2024/11/28 16:31:37

前言

在安卓源码里,离不开两个东西,一个就是.sh文件,还有一个就是.mk文件。

这两个文件各持有一个语法,一个是Makefile语法,一个是Shell脚本语法。

这两个是真的让我头疼,就像看天书一样,呜呜呜。


文章目录

  • 前言
  • 1、变量
    • 1)变量输出长度
    • 2)提取子字符串
    • 3)查找子字符串
    • 4)单引号和双引号的区别
    • 5)特殊变量
    • 6)脚本里变量的赋值情况
    • 7)变量存储命令的内容
    • 8)环境变量
  • 2、数组
    • 1)定义数组
    • 2)读取数组
    • 3)关联数组
  • 3、注释
  • 4、运算符
    • 1)算术运算符
    • 2)关系运算符
    • 3)布尔运算符
    • 4)逻辑运算符
    • 5)字符串运算符
    • 6)文件测试运算符
  • 5、输入输出
    • 1)read(输入)
    • 2)echo(输出)
    • 3)printf(输出)
      • printf的特殊用法
  • 6、流程控制
    • 1)if
    • 2)for
    • 3)while
    • 4)until
    • 5)case
    • 6)break和continue
  • 7、函数
    • 1)函数返回值
    • 2)带参函数
  • 8、输入输出重定向
    • 1)输出重定向
    • 2)输入重定向
    • 3)特殊重定向
    • 4)Here Document
    • 5)/dev/null 文件
  • 9、文件包含(引用)


1、变量

完整的变量打印:

name="乌鸡哥"
echo ${name}

简写:

name="乌鸡哥"
echo $name

乌鸡哥

实例:
变量
一开始没有namess这个变量,所以没有输出。

后来我添加了,就有输出了。

最后我删除了变量namess,又没有输出了。


1)变量输出长度

name="乌鸡哥"
echo ${#name}

4


2)提取子字符串

以下实例从字符串第 2 个字符开始截取 4 个字符:

string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

注意:第一个字符的索引值为 0。


3)查找子字符串

查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):

string="runoob is a great site"
echo `expr index "$string" io`  # 输出 4

注意: 以上脚本中 ` 是反引号,而不是单引号 ',不要看错了哦。

4)单引号和双引号的区别

在 shell 脚本中,echo 命令用于输出字符串或者变量的值。在使用 echo 命令时,可以使用反引号、单引号或双引号来包围要输出的内容。

你们猜猜下面打印结果是什么?

name="乌鸡哥"
name2='${name}'
name3="${name}"
...
echo $name
echo $name2

结果如下:

乌鸡哥
${name}
乌鸡哥

  1. 反引号(``):反引号用于将要执行的命令包围起来,并将命令的输出作为参数传递给 echo 命令。例如:

    echo "Today is `date +%A`"
    

    这个命令会将 date +%A 命令输出的结果插入到 echo 命令中进行输出。

  2. 单引号('):单引号用于将其中的内容视为字面值进行输出,不进行任何解释和替换。例如:

    echo 'The value of $HOME is' $HOME
    

    这个命令会输出 The value of $HOME is /home/user,其中 $HOME 被视为普通字符输出,而不会被解释为变量。

  3. 双引号("):双引号用于将其中的内容进行变量替换和转义解析等操作,并将其作为一个整体进行输出。例如:

    name='John'
    echo "Hello, $name!"
    

    这个命令会输出 Hello, John!,其中 $name 会被自动替换为变量的值。

需要注意的是,在使用双引号和反引号时,如果其中包含特殊字符或者空格等不安全的字符,需要进行适当的转义处理,以避免出现意外的错误。

单引号变量,不识别特殊语法;
双引号变量,识别特殊符号。

5)特殊变量

查看上条命令是否执行成功。

  • $?
    • 0:成功
    • 1-255:错误码

实例:

在这里插入图片描述

另外,还有几个特殊字符用来处理参数(调用函数传参,命令行传参等…):

  • $*:以一个单字符串显示所有向脚本传递的参数。如$*用「“」括起来的情况、以”$1 $2 … $n"的形式输出所有参数。
  • $@:与$*相同,但是使用时加引号,并在引号中返回每个参数。如$@用「“」括起来的情况、以”$1" “ 2 " … " 2" … " 2""n” 的形式输出所有参数。
  • $$:脚本运行的当前进程ID号
  • $!:后台运行的最后一个进程的ID号
  • $#:传递到脚本的参数个数
  • $-:显示Shell使用的当前选项,与set命令功能相同。
  • $?:显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。还有一个作用就是函数返回值在调用该函数后通过 $? 来获得

6)脚本里变量的赋值情况

  1. 每次调用bash/sh解释器,都会开启一个子shell,不保留当前的shell变量,通过pstree检查进程树。(用bash执行脚本里面的变量赋值不被保存)
  2. source.是在当前shell环境加载脚本,因此保留变量。(用source执行脚本里面的变量赋值会被保存)
    变量的特殊情况

7)变量存储命令的内容

name=ls
#显示ls
echo $name
name='ls'
#显示当前目录的文件
echo ${name}

8)环境变量

环境变量一般指的是用export内置命令导出的变量,用于定义shell的运行环境、保证shell命令的正确执行。

shell通过环境变量确定登录的用户名、PATH路径、文件系统等各种应用。环境变量可以在命令行中临时创建,但是用户退出shell终端,变量即丢失,如要永久生效,需要修改环境变量配置文件。

某个远程登录用户专属配置文件(局部变量)

  • ~/.bash_profile(系统优先加载所有全局环境变量和 shell 函数)
  • ~/.bashrc (在 ~/.bash_profile中被加载,相当于套娃),用户在登录的时候会去加载~/.bash_profile~/.bashrc文件

所有用户共有(全局变量)

  • /etc/profile (系统优先加载)
  • /etc/bashrc ,且系统建议最好创建在 /etc/profile.d/,而非直接修改主文件,修改全局配置文件,影响所有登录系统的用户

在 Linux 和类 Unix 系统中,全局的 Bash Shell 配置数据通常被保存在 /etc/profile 与 /etc/bashrc 文件中。这些文件包含所有用户共享的系统级别的配置和环境变量信息。

当操作系统启动时,Bash Shell 会首先执行 /etc/profile 脚本以加载所有全局环境变量和 shell 函数。对于每个新的 Bash 终端窗口,系统还将自动执行 /etc/bashrc 文件中的某些特定配置命令。

在更推荐的做法是创建自己的配置脚本并将其存储在 /etc/profile.d/ 目录下。这样,管理员可以随意创建单独的配置文件来自定义系统级别的平台和服务特定参数,而不必修改 /etc/profile 或 /etc/bashrc 文件。

例如,可以为每个服务或应用程序创建单独的配置文件,并将其放置在 /etc/profile.d/ 目录中,该目录中的任何 .sh 文件都会被整合到系统全局的 Bash 环境中。最后,每次启动新的 Bash 终端窗口时,系统都会自动执行这些文件中包含的命令和设置环境变量,实现系统环境的自动化配置。

检查系统环境变量的命令

  • set:输出所有变量,包括全局变量、局部变量
  • env:只显示全局变量
  • declare:输出所有的变量,如同set
  • export:显示和设置环境变量值

撒销环境变量

  • unset+变量名,删除变量或函数

设置只读变量

  • readonly:只有shell结束,只读变量才失效
直接readonly 显示当前系统只读变量
[root@chaogelinux ~]# readonly name="超哥
[root@chaogelinux ~]# name="chaochao"
-bash: name: 只读变量

2、数组

支持一维数组(不支持多维数组),并且没有限定数组的大小,数组元素的下标由 0 开始编号。

1)定义数组

在 Shell 中,用括号来表示数组,初始化时不需要定义数组大小(与 PHP 类似),数组元素用"空格"符号分割开。定义数组的一般形式为:

数组名=(值1 值2 … 值n)

array_name=(A B "C" D)

还可以单独定义数组的各个分量

数组名[下标值]=变量值

array_name[0]=value0

2)读取数组

读取数组元素值的一般格式是:

# ${数组名[下标]}
valuen=${array_name[n]}

例如:

#使用 @ 符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}

#我们尝试打印一下数组元素。
array_name=(A B "C" D)

echo "第二个元素为: ${array_name[1]}"
echo "第三个元素为: ${array_name[2]}"

打印出来后你觉得加了双引号的会有区别吗?
答案是没有哦,打印出来都一样。

B
C


最后

#结合上述知识点

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

3)关联数组

declare 是一个 shell 内置命令,在 Linux 和其他类 Unix 系统中都可以使用。它用于声明变量的类型和属性,以及定义函数等。下面是一些 declare 命令的常见用法:

  1. 声明普通变量
declare variable_name=value

这个命令将创建一个名为 variable_name 的变量,并将其初始化为指定的值。

  1. 声明只读变量
declare -r variable_name=value

这个命令将创建一个只读的名为 variable_name 的变量,并将其初始化为指定的值。只读变量的值不能被修改或重新赋值。

  1. 声明整数变量
declare -i variable_name=value

这个命令将创建一个名为 variable_name 的整型变量,并将其初始化为指定的值。如果后续对该变量进行了非整型的赋值操作,系统会尝试自动转换为整型。

  1. 声明数组变量
declare -a array_name

这个命令将创建一个名为 array_name 的数组变量。在后续的操作中,可以使用数组下标来访问和赋值数组元素。

  1. 声明关联数组变量
declare -A associative_array_name

这个命令将创建一个名为 associative_array_name 的关联数组变量。在后续的操作中,可以使用任意字符串作为数组下标来访问和赋值数组元素。

  1. 声明函数
declare -f function_name

这个命令将打印名为 function_name 的函数的定义。如果不加参数,则会列出所有已经定义的函数。

除了上述用法外,declare 命令还支持一些其他的选项和参数,可以通过 help declare 命令来查看它们的详细说明。

我们这里详细介绍第五点

在 Bash shell 中,关联数组(associative array)是一种特殊的数组类型,它使用任意字符串作为下标来访问和赋值数组元素。关联数组也被称为哈希表(hash table)、字典(dictionary)或映射(map)。

要声明一个关联数组变量,可以使用 declare 命令的 -A 选项,例如:

declare -A my_array

也可以这样直接定义:

declare -A my_array=(["name"]="John" ["age"]="30")

这里,我们使用关联数组下标 "name""age" 来分别给数组元素赋值。

my_array["name"]="John"
my_array["age"]=30

在后续的操作中,可以使用任何字符串作为数组下标来访问和赋值数组元素,例如:

echo "My name is ${my_array["name"]} and I am ${my_array["age"]} years old."

打印数组的所有value:

# 两者等效
echo "数组的元素为: ${my_array[*]}"
echo "数组的元素为: ${my_array[@]}"

数组的元素为: John 30

打印数组的所有key:

echo "数组的键为: ${!site[*]}"
echo "数组的键为: ${!site[@]}"

数组的键为: name age

打印数组的元素个数:

echo "数组元素个数为: ${#my_array[*]}"
echo "数组元素个数为: ${#my_array[@]}"

数组元素个数为: 2

需要注意的是,在关联数组中,每个元素都与一个独立的字符串键相关联。因此,在访问数组元素时,可以使用任何合法的字符串作为下标,包括空字符串、特殊字符和空格等。与普通数组不同,关联数组不需要事先指定数组的长度,也不需要在定义时初始化数组元素。


3、注释

# 别学习了 好好睡觉(单行注释)
# 多行注释(Here Document)
: <<END_COMMENT
注释内容...
注释内容...
注释内容...
END_COMMENT
# 举个栗子
# 这段代码先执行 Here Document (<<)语法结构,可以看成标准输入
# 将内容传递给 cat 命令作为标准输入
# 然后再将 cat 命令的输出结果重定向(>)到文件中
# 最终将字符串 "五级五级" 和 "66666666" 写入到 77.sh 文件中。
cat > device/$1/$2/vendorsetup.sh << EOF
echo "五级五级"
echo "66666666"
EOF

4、运算符

1)算术运算符

就是加减乘除and so on。

条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成[ $a == $b ]

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 $b / $a`
echo "b / a : $val"

val=`expr $b % $a`
echo "b % a : $val"

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

2)关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

  • -eq:相等
  • -ne:不相等
  • -gt:左边大于右边
  • -lt:左边小于右边
  • -ge:左边大于等于右边
  • -le:左边小于等于右边
a=10
b=20

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

3)布尔运算符

  • !:非
  • -o:或
  • -a:与
a=10
b=20

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

4)逻辑运算符

a=10
b=20

if [[ $a -lt 100 && $b -gt 100 ]]
then
   echo "返回 true"
else
   echo "返回 false"
fi

if [[ $a -lt 100 || $b -gt 100 ]]
then
   echo "返回 true"
else
   echo "返回 false"
fi

5)字符串运算符

a="abc"
b="efg"

#检测两个字符串是否相等,相等返回true
if [ $a = $b ]
then
   echo "$a = $b : a 等于 b"
else
   echo "$a = $b: a 不等于 b"
fi
#检测两个字符串是否不相等,不相等返回true
if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"
else
   echo "$a != $b: a 等于 b"
fi
#检测字符串长度是否为0,为0返回true
if [ -z $a ]
then
   echo "-z $a : 字符串长度为 0"
else
   echo "-z $a : 字符串长度不为 0"
fi
#检测字符串长度是否不为0,不为0返回true
if [ -n "$a" ]
then
   echo "-n $a : 字符串长度不为 0"
else
   echo "-n $a : 字符串长度为 0"
fi
#检测字符串是否不为空,不为空返回true
if [ $a ]
then
   echo "$a : 字符串不为空"
else
   echo "$a : 字符串为空"
fi

6)文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。

1

file="/var/www/runoob/test.sh"
if [ -r $file ]
then
   echo "文件可读"
else
   echo "文件不可读"
fi

5、输入输出

1)read(输入)

read -p "input your name:" str
echo "read name: $str"  

2)echo(输出)

echo `date`

3)printf(输出)

格式说明:

printf  format-string  [arguments...]

参数说明:

  • format-string: 为格式控制字符串
  • arguments: 为参数列表

举个栗子:

printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg 
  • %-10s:指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
  • %-4.2f :指格式化为小数,其中 .2 指保留2位小数
  • %s :输出一个字符串
  • %d :整型输出
  • %c :输出一个字符
  • %f :输出实数,以小数形式输出
# format-string为双引号
printf "%d %s\n" 1 "abc"

# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"

# 没有引号也可以输出(没换行)
printf %s abcdef

# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用(没换行)
printf %s abc def

printf "%s\n" abc def

printf "%s %s %s\n" a b c d e f g h i j

# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"

1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j
and 0

printf的特殊用法

1


6、流程控制

1)if

正常格式:

if 条件1
then
    命令1 
    命令2
    ...
    命令N 
fi

简写一行模式:

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

多if-elseif-else模式:

if 条件1
then
    命令1
elif 条件2 
then 
    命令2
else
    命令N
fi

if else 的 ["$a" -gt "$b"]判断条件中大于使用 -gt,小于使用 -lt。
if else 的 ((a>b)) 判断条件中大于和小于可以直接使用 > 和 <。
if else 语句经常与 test 命令结合使用。


2)for

一般格式:

for var in item1 item2 ... itemN
do
    命令1
    命令2
    ...
    命令N
done

简写一行模式:

for var in item1 item2 ... itemN; do 命令1; 命令2… done;
for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done
#!/bin/bash

for str in This is a string
do
    echo $str
done

This
is
a
string


3)while

一般格式:

while 条件
do
    # 可以在这里添加自己的命令
done
#!/bin/bash
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done
echo '按下 <CTRL-D> 退出'
echo -n '输入你最喜欢的网站名: '
while read FILM
do
    echo "是的!$FILM 是一个好网站"
done

在 Linux 终端中,按下 Ctrl+d 键可以执行以下不同的功能,具体取决于当前终端的上下文:

  1. 输入结束标志:当您想要从终端输入流中退出时,按下 Ctrl+d 可以指示输入结束。例如,在命令行中通过管道(|)将输出重定向到某个命令或文件中时,您可以按 Ctrl+d 表示完成输入并开始处理。

  2. 终止一个前台进程:如果您正在运行一个前台进程并想要强制停止它,可以使用 Ctrl+d 组合键来发送 SIGINT 信号。该信号会告诉应用程序停止当前操作和任何正在进行的数据处理,并退出进程。

  3. 登出当前用户:在大多数 Linux 系统中,按下 Ctrl+d 可以表示退出当前登录用户。这通常与 shell 或其他 CLI 应用程序一起使用。

总之,Ctrl+d 多种多样的作用,具体取决于您当前使用的终端上下文。在使用时,请注意其所附带的含义,并小心操作。

无限循环:

while :
do
    # 可以在这里添加自己的命令
donewhile true
do
    # 可以在这里添加自己的命令
donefor (( ; ; ))
do
   echo "loop will run forever unless you terminate it with Ctrl+c"
   # 可以在这里添加自己的命令
done


4)until

until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。

until 条件
do
    # 可以在这里添加自己的命令
done
a=0
# 输出0-9
until [ ! $a -lt 10 ]
do
   echo $a
   a=`expr $a + 1`
done

5)case

值可以为变量或常数

一般格式:

casein
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
    1)  echo '你选择了 1'
    ;;
    2)  echo '你选择了 2'
    ;;
    3)  echo '你选择了 3'
    ;;
    4)  echo '你选择了 4'
    ;;
    *)  echo '你没有输入 1 到 4 之间的数字'
    ;;
esac
site="runoob"

case "$site" in
   "runoob") echo "菜鸟教程"
   ;;
   "google") echo "Google 搜索"
   ;;
   "taobao") echo "淘宝网"
   ;;
esac

6)break和continue

结束循环和跳出一层循环。同Java


7、函数

linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。

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

1)函数返回值

funWithReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum$anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"

函数返回值在调用该函数后通过 $? 来获得。

2)带参函数

funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

注意:$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。


8、输入输出重定向

就是把文件内容搞过来,或者搞过去。

1)输出重定向

把乌鸡哥三个字放到这个77.txt文件中

$ echo "乌鸡哥" > 77.txt

2)输入重定向

wc -l < 文件名

其中,wc 是一个统计文本信息的命令,-l 参数表示只统计行数。< 符号表示将文件内容作为输入传入到命令中。

因此,执行这个命令后,它会读取文件 “users” 的内容,并统计其中的行数,然后输出结果。这个命令在 Unix 或 Linux 环境下经常用于查看文件的行数。


sort < input.txt > output.txt

input.txt读取文件,然后用sort排序,最后排完了再输出到output.txt


3)特殊重定向

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
ls /mnt 2>> log.txt

这个命令尝试列出 /mnt 目录中的内容。如果操作成功,则结果将直接打印到终端上;但是,如果操作失败,命令将记录相关错误信息,把错误信息通过追加的方式写入到 log.txt 文件中。当您想要获取输出并将其保存在文件中时,这种重定向技术特别有用。

ls /mnt > output.txt 2>&1

这个命令尝试列出 /mnt 目录中所有的内容。如果目录可以访问,则命令将把结果列表格式输出到 output.txt 文件中,不论这些结果是标准输出还是标准错误输出。如果存在任何错误或警告信息,则它们也将被重定向到该文件中,使您可以轻松快速地查看所有输出。注意,在使用此语法时,请确保您有足够的权限来访问输入和输出文件,并且不会覆盖或修改意外文件。


4)Here Document

Here Document 是一种在 Bash/Shell 脚本中用于向命令提供输入的语法。它允许您指定一个“限定词”(也称为分界符),然后在该分界符下方的多行文本将作为命令的标准输入进行处理。

在脚本中,Here Document 语法通常采用以下形式:

command <<LIMITER
input text
...
LIMITER

其中:

  • command 表示要接收 Here Document 作为输入的命令。
  • << 符号用于指定 Here Document 分界符,并将其留空以让 Shell 可以自动选择默认值。
  • LIMITER 是由用户指定的分界符,用于隔离输入文本并告诉 Shell 在何时停止读取标准输入。
  • input text 是最终传递给命令作为标准输入的多行文本。

注意,分界符必须从第一列开始,因此不能缩进 Here Document 中的文本。另外,当您需要在输入文本中使用变量或其他 Bash 命令时,可以在限定词前加上一个“-”符号,例如 <<-LIMITER,这会告诉 Shell 忽略输入文本中的缩进(就像 Bash 中的 heredoc 标记)。

例如,以下是一个使用 Here Document 语法的示例:

cat <<END
This is some example text that will be passed
as standard input to the cat command.
It can contain multiple lines.
END

这将创建一个名为 END 的分界符(END也可以换成pp啥都可以),并将三行文本作为标准输入传递给 cat 命令。最终,命令会将输入文本作为输出打印到终端上。


5)/dev/null 文件

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:

$ command > /dev/null

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

如果希望屏蔽 stdout 和 stderr,可以这样写:

$ command > /dev/null 2>&1

注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

这里的 2 和 > 之间不可以有空格,2> 是一体的时候才表示错误输出。


9、文件包含(引用)

和C语言差不多,也可以引用其他.sh脚本里面的函数、变量等等。

. filename   # 注意点号(.)和文件名中间有一空格source filename

创建两个 shell 脚本文件

A.sh文件

#!/bin/bash
name="乌鸡哥"

B.sh文件

#!/bin/bash
#使用 . 号来引用test1.sh 文件
. ./test1.sh

# 或者使用以下包含文件代码
# source ./test1.sh

echo "${name}"

$ chmod +x B.sh
$ ./B.sh
乌鸡哥

被包含的文件 A.sh 不需要可执行权限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/474351.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql为json字段创建索引的两种方式

目录 一、前言二、通过虚拟列添加索引&#xff08;Secondary Indexes and Generated Columns&#xff09;三、多值索引&#xff08;Using multi-valued Indexes&#xff09;四、官网地址 一、前言 JSON 数据类型是在mysql5.7版本后新增的&#xff0c;同 TEXT&#xff0c;BLOB …

国内首款多节点/无需密钥/无需登录的ChatGPT客户端开源项目

在这个AI浪潮推动下&#xff0c;涌现了一大批“参差不齐”的GPT产品&#xff0c;有的一直在更新迭代&#xff0c;有的不断升级乃至付费订阅&#xff0c;有的中途停止运营。在这个AI产品也需要优胜劣汰的时代下&#xff0c;谁能够“谁主沉浮&#xff0c;且看今朝&#xff01;”&…

Ansible的基础了解

目录 第一章.Ansible概述 1.1.Ansible是什么 1.2.Ansible的特性和过程 1.3.ansible 具有如下特点&#xff1a; 1.4.Ansible的四个组件 1.5.ansible 核心程序 1.6.ansible执行的过程 第二章.Ansible 环境安装部署 2.1.实验环境&#xff0c;安装部署 第三章.ansible 命…

BLE调制与解调的一些东西

BLE调制 BLE是GFSK的IQ调制 IQ调制 所谓IQ调制&#xff0c;就是利用IQ两个分量序列去控制两路正交信号&#xff0c;I和Q两个序列可以是任意数字&#xff0c;也可以是符合某些规律的序列。 总的原理公式就是&#xff1a; cos(ab)cos(a)cos(b)-sin(a)sin(b) Acos(b)-Bsin(b)M…

音视频 FFmpeg

文章目录 前言视频编解码硬件解码(高级)软解码(低级)软、硬解码对比视频解码有四个步骤Android 系统中编解码器的命名方式查看当前设备支持的硬解码 基础知识RGB色彩空间常见的格式对比YUV索引格式分离RGB24像素数据中的R、G、B分量 BMP 文件格式格式组成像素排列顺序RGB24格式…

双指针技巧总结

一、双指针技巧——情景1 通常&#xff0c;我们只需要一个指针进行迭代&#xff0c;即从数组中的第一个元素开始&#xff0c;最后一个元素结束。然而&#xff0c;有时我们会使用两个指针进行迭代。 双指针的典型场景 (1)从两端向中间迭代数组。 (2)一个指针从头部开始&#…

Spark RDD (Resilient Distributed Datasets) 弹性分布式数据集

设计需求 Spark RDD 的设计目的是为了实现快速、可扩展和容错的数据处理。它是一个不可变的分布式数据集&#xff0c;可以在集群中分布式存储和处理数据。RDD 提供了一系列操作来处理数据&#xff0c;包括转换操作和行动操作。转换操作可以将一个 RDD 转换为另一个 RDD&#x…

Arduino学习笔记4

一.声控灯实验 1.源代码 int led2;//定义板子上数字2口控制小灯 int flag0;//定义一个变量记录小灯是亮起还是熄灭 int shengyin3;//定义声音传感器的控制口void setup() {pinMode(led,OUTPUT);//定义小灯为输出模式pinMode(shengyin,INPUT);//定义声音控制口为输入模式 } vo…

python+Django社区疫情防控系统 uniapp微信小程序

随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&#xf…

[jenkins自动化2]: linux自动化部署方式之流水线(下篇)

目录 1. 引言: 2. 进阶操作 流水线 -> 2.1 简介: -> 2.2 最终效果图展示: -> 2.3 有没有心动, 真的像流水线一样, 实现了一键部署启动 3. 实现方式 3.1 下载几个插件 3.2 创建流水线任务 3.3 点击配置 3.4 根据流水线语法 写一个简单的helloworld 3.5 执行…

数字化医院PACS影像系统 三维影像后处理技术应用

PACS影像存取与传输系统以实现医学影像数字化存储、诊断为核心任务&#xff0c;从医学影像设备&#xff08;如CT、CR、DR、MR、DSA、RF等&#xff09;获取影像&#xff0c;集中存储、综合管理医学影像及病人相关信息&#xff0c;建立数字化工作流程。 PACS系统可实现检查预约、…

【C++入门】内联函数

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】 目录 什么是内联函数内联函数特性 什么是内联函数 内联函数概念&#xff1a; 内联函数就是以inline修饰的函数叫做内联函数&a…

No.051<软考>《(高项)备考大全》【冲刺5】《软考之 119个工具 (3)》

《软考之 119个工具 &#xff08;3&#xff09;》 41.进度计划编制工具:42.绩效审查:43.卖方投标分析:44.质量成本:45.成本汇总:46.历史关系:47.资金限制平衡:48.挣值管理:49.预测:50.完工尚需绩效指数:51.成本效益分析:52.试验设计:53.七种基本质量工具:54.统计抽样:55.其他质…

Linux拓展:链接库

一.说明 本篇博客介绍Linux操作系统下的链接库相关知识&#xff0c;由于相关概念已在Windows下链接库一文中介绍&#xff0c;本篇博客直接上操作。 二.静态链接库的创建和使用 1.提前看 这里主要介绍的是C语言的链接库技术&#xff0c;而在Linux下实现C语言程序&#xff0c…

Web入门脚本三:一键完成与dex的交互,羊毛党必备

前言 该脚本用途&#xff1a;一键可以完成与dex的所有交互&#xff0c;包括2次swap&#xff0c;添加/移除流动性&#xff0c;以及farm和提取LP。一次运行可以有6条交易记录。 无论是个人单刷还是羊毛党批量地址刷交互都完美适配。当然反女巫方案不在这次文章的讨论范围内。 一、…

Python快速入门,看这一篇就够了

大家好&#xff0c;我是老三&#xff0c;我最近在看一些人工智能相关的东西&#xff0c;大部分相关的框架&#xff0c;都是用Pyhon写的。 老三会用Python&#xff0c;但谈不上多熟练&#xff0c;最近准备拿Python作为自己的第二语言&#xff0c;那么这期我们来一起快速梳理一下…

程序员该如何学习技术

程序员该如何学习技术 前言 学习是第一生产力&#xff0c;我从来都是这么认为的&#xff0c;人只有只有不断地学习才能意识到自己的缺点和不足&#xff0c;身为程序员&#xff0c;我更认为人们应当抱着终身学习的想法实践下去&#xff0c;这是我所一直践行且相信的。 高处不胜寒…

体验 GPT-4 后,回顾 OpenAI 发展历程及感悟

从 ChatGPT Plus 发布第一天就开始重度使用&#xff0c;刚刚和新发布的 GPT-4 进行了 20 多轮对话&#xff0c;来简单介绍下这几个模型背后的技术&#xff0c;并且分享下感受。 GPT 在发展历程中&#xff0c;一共经历了 4 个阶段&#xff0c;分别是 1、2、3、4。这几个阶段分别…

【VM服务管家】VM4.x算法模块开发_4.3 联合Halcon开发

目录 4.3.1 联合开发&#xff1a;集成HALCON第三方算子到VM工具箱的方法 4.3.1 联合开发&#xff1a;集成HALCON第三方算子到VM工具箱的方法 描述 环境&#xff1a;VM4.0及以上 VS2013 问题&#xff1a;有的用户在使用VisionMaster软件在开发视觉项目时&#xff0c;可能同时也…