Linux shell脚本中特殊字符含义有哪些

Linux Shell脚本中,预定义了一些特殊参数,它们分别代表不同的含义和返回值,下面逐一进行总结。

1. 【$0】:脚本名

$0返回当前执行的shell脚本的名称。

2.【1-9】:命令行参数1到9

$1-$9这9个分别代表脚本执行命令第一个参数、第二个参数、第三个参数……第9个参数。

例如,假设我们有一个名为 test.sh 的Shell脚本,它的内容如下:

#!/bin/bash

echo "Script name: $0"
echo "First argument: $1"
echo "Second argument: $2"

在运行脚本时,我们可以给它传递两个参数,比如:

./test.sh hello world

这时候脚本会输出:

Script name: test.sh
First argument: hello
Second argument: world

说明 代表脚本名,1 代表第一个参数,$2代表第二个参数。

3.【 $#】:参数个数

它表示所有参数的个数。

#!/bin/bash

echo "Number of arguments: $#"

运行脚本 ./test.sh hello world,输出 Number of arguments: 2

4. 【$*】:所有参数

$*表示所有参数。

#!/bin/bash

echo "All arguments: $*"

运行脚本 ./test.sh hello world,输出 All arguments: hello world

5. 【$@】:所有参数

$@也表示所有参数:

#!/bin/bash

echo "All arguments: $@"

运行脚本 ./test.sh hello world,输出 All arguments: hello world

上面$*和$@都是用来获取所有脚本参数的特殊变量。它们之间的区别在于,如何将参数作为单个字符串或多个独立字符串进行处理。

  • $*会把所有的参数解释成一个单词(单个字符串),即每个参数之间不会加上空格,全部组合成一个字符串,用IFS(默认是空格)分隔。所以,将*放在双引号里,预处理$符号,保持长字符串的完整性:
#!/bin/bash

echo "Using \$*:"
for arg in "$*"; do
    echo $arg
done
  • $@会把所有的参数看成是独立的单词(多个独立的字符串),即每个参数之间加上空格,将每个参数作为一个独立的字符串处理。
#!/bin/bash

echo "Using \$@:"
for arg in "$@"; do
    echo $arg
done

下面我们可以通过一个示例来理解两者的区别。假设我们有一个shell脚本,名为 test.sh 并拥有以下内容:

#!/bin/bash

echo "Using \$*:"
for arg in "$*"; do
    echo $arg
done

echo "Using \$@:"
for arg in "$@"; do
    echo $arg
done

然后,在终端上执行以下命令:

$ ./test.sh one two three

当我们执行脚本时,输出如下所示:

Using $*:
one two three
Using $@:
one
two
three

我们可以看到,使用时,所有参数都解释为单个字符串,由空格分隔。

而使用@时,每个参数都被解释为一个单独的字符串,并独立处理。

在大多数情况下,使用$@是更加灵活和安全的选项,因为它可以独立处理每个参数,而不会将它们合并为单个字符串。

6. 【$?】:上一个命令的退出状态码

#!/bin/bash

ls /
echo "Exit status code: $?"

由于ls /应该会执行成功,因此运行脚本后输出 Exit status code: 0,表示上一个命令执行成功。

7. 【$$】:当前进程ID号

$$ 是一个特殊的变量,用于获取当前正在运行的Shell脚本的进程ID(PID)

这个变量对于在Shell脚本中跟踪和识别进程非常有用,或者将PID用于生成唯一的临时文件名。

以下是一个简单的示例脚本,它使用$$变量来创建一个唯一的临时文件名:

#!/bin/bash

tempfile=/tmp/myprog.$$

echo "Program is running with PID $$."
echo "Temp filename is $tempfile."

#rest of the script goes here...

在上述示例中,我们使用了$$变量来创建一个唯一的文件名,将其存储在$tempfile变量中,并在控制台输出当前脚本运行的进程ID。这个唯一的文件名将被用于存储程序输出或其他的过程。

使用$$变量时,需要注意它只能获取当前Shell脚本的PID而不能获取任何子进程或后台任务的PID

8. 【$!】:最近一次在后台运行的进程的PID号

在Linux Shell脚本中,!是一个特殊变量,用于获取最近一次在后台运行的进程的PID号(进程ID号)。

通常用于在脚本中启动后台进程,并且需要获取后台进程的PID号。

以下是一个示例脚本 test.sh,它使用&运算符来将程序启动到后台运行,并使用$!变量获取需要的PID号:

#!/bin/bash

echo "Starting background process..."
sleep 5 &
background_pid=$!
echo "The background process PID is: $background_pid"

上述脚本中的sleep命令会在后台执行5秒钟,并执行$!将其PID号赋值给变量background_pid

最后,脚本会输出后台进程的PID号。

执行该脚本的命令是:./test.sh,其输出如下:

Starting background process...
The background process PID is: 12345

其中,12345应该是实际执行中sleep进程的PID号,其值随机。

9. 【$-】:获取当前Shell的选项标志

$- 是一个特殊变量,用于获取当前Shell的选项标志(Option Flags)。选项标志是Shell用来控制其行为的一些特殊设置。

$- 可以用来获取当前Shell所使用的选项标志,通常应用于Shell脚本的调试中,可以帮助我们诊断问题。

以下是一个示例脚本 test.sh,它使用$-变量获取当前Shell的选项标志及其含义:

#!/bin/bash

echo "Value of \$-: $-"

上述脚本中,echo命令会输出当前Shell的选项标志。

执行该脚本的命令是:./test.sh,其输出如下:

Value of $-: himBH

上述输出中,选项标志中包含了5个字符,分别表示以下内容:

  • hbash shell启用hash命令时将完成命令名和缓存条目之间的HASH值打印到标准错误输出中;
  • i:交互模式运行,即标准输入与终端相连;
  • m:启用作业控制功能;
  • B:启用Brace Expansion(花括号扩展)机制;
  • HShell扩展历史记录功能,寻找法:$HOME/.bash_history,如果该文件不存在则新建一个。

10. 【$IFS】:指定Shell脚本中的字段分隔符

$IFS是一个特殊变量,用于指定Shell脚本中的字段分隔符。字段分隔符是将一行输入或输出按照不同的字段拆分开来并存储在不同的变量中的标记。

默认情况下,$IFS的值为空格,制表符和换行符。但是,我们可以将其设置为其他的分隔符来满足特定的需求。

以下是一个示例脚本 test.sh,它使用$IFS变量来指定不同的分隔符,将一行输入按照分隔符分成不同的变量:

#!/bin/bash

echo "Enter a line of values separated by commas (','):"
read line

echo "Default IFS values: '$IFS'"
IFS=","
echo "Custom IFS value set to: '$IFS'"

echo "Values entered:"
for value in $line
do
    echo "$value"
done

上述脚本中,通过read命令读取一行输入,并通过将$IFS设置为逗号来将输入行分隔成不同的变量。最后,使用for循环按顺序输出不同的变量。

执行该脚本的命令是:./test.sh,它会提示用户输入一个以逗号分隔的值列表。然后,它将逗号设置为分隔符并按顺序输出每个值。下面是一些示例输入和输出:

输入:

a,b,c,d,e

输出:

Default IFS values: '  \n'
Custom IFS value set to: ','
Values entered:
a
b
c
d
e

在上述输出中,$IFS的初始值为默认值(空格、制表符、换行符),该输入字符串以逗号分隔,然后按逗号分隔的方式打印每个值。

这是一个非常有用的用法,可以将一行以逗号或其他字符分隔的值按分隔符分成不同的变量,进一步处理这些变量值。

关于shell中这10个特殊变量,总结如下:

图片[1]-Linux shell脚本中特殊字符含义有哪些-不念博客
© 版权声明
THE END