在Linux Shell脚本中,预定义了一些特殊参数,它们分别代表不同的含义和返回值,下面试着借用ChatGTP辅助写作进行总结并举例:
1. $0:脚本名
$0返回当前值行的shell脚本的名称。
2.$1-$9
:命令行参数1到9
$1-$9
这9个分别代表脚本执行命令第一个参数、第二个参数、第三个参数……第9个参数。
例如,假设我们有一个名为 test.sh
的Shell脚本,它的内容如下:
#!/bin/bashecho "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/bashecho "Number of arguments: $#"
运行脚本 ./test.sh hello world
,输出 Number of arguments: 2
4. $*: 所有参数
$*表示所有参数。
#!/bin/bashecho "All arguments: $*"
运行脚本 ./test.sh hello world
,输出 All arguments: hello world
5. $@: 所有参数
$@也表示所有参数,
#!/bin/bashecho "All arguments: $@"
运行脚本 ./test.sh hello world
,输出 All arguments: hello world
上面$*和$@
都是用来获取所有脚本参数的特殊变量。它们之间的区别在于,如何将参数作为单个字符串或多个独立字符串进行处理。
$*
会把所有的参数解释成一个单词(单个字符串),即每个参数之间不会加上空格,全部组合成一个字符串,用"IFS"(默认是空格)分隔。所以,将*
放在双引号里,预处理$
符号,保持长字符串的完整性:
#!/bin/bashecho "Using \$*:"
for arg in "$*"; doecho $arg
done
$@
会把所有的参数看成是独立的单词(多个独立的字符串),即每个参数之间加上空格,将每个参数作为一个独立的字符串处理。
#!/bin/bashecho "Using \$@:"
for arg in "$@"; doecho $arg
done
下面我们可以通过一个示例来理解两者的区别。假设我们有一个shell脚本,名为 test.sh
并拥有以下内容:
#!/bin/bashecho "Using \$*:"
for arg in "$*"; doecho $arg
doneecho "Using \$@:"
for arg in "$@"; doecho $arg
done
然后,在终端上执行以下命令:
$ ./test.sh one two three
当我们执行脚本时,输出如下所示:
Using $*:
one two three
Using $@:
one
two
three
我们可以看到,使用∗
时,所有参数都解释为单个字符串,由空格分隔。而使用@
时,每个参数都被解释为一个单独的字符串,并独立处理。在大多数情况下,使用$@
是更加灵活和安全的选项,因为它可以独立处理每个参数,而不会将它们合并为单个字符串。
6. $?: 上一个命令的退出状态码
#!/bin/bashls /
echo "Exit status code: $?"
由于ls /
应该会执行成功,因此运行脚本后输出 Exit status code: 0
,表示上一个命令执行成功。
7. $$:当前进程ID号
$$
是一个特殊的变量,用于获取当前正在运行的Shell
脚本的进程ID(PID)
。
这个变量对于在Shell
脚本中跟踪和识别进程非常有用,或者将PID
用于生成唯一的临时文件名。
以下是一个简单的示例脚本,它使用$$
变量来创建一个唯一的临时文件名:
#!/bin/bashtempfile=/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/bashecho "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/bashecho "Value of \$-: $-"
上述脚本中,echo
命令会输出当前Shell的选项标志。
执行该脚本的命令是:./test.sh
,其输出如下:
Value of $-: himBH
上述输出中,选项标志中包含了5个字符,分别表示以下内容:
- h:bash shell启用hash命令时将完成命令名和缓存条目之间的HASH值打印到标准错误输出中;
- i:交互模式运行,即标准输入与终端相连;
- m:启用作业控制功能;
- B:启用Brace Expansion(花括号扩展)机制;
- H:Shell扩展历史记录功能,寻找法:$HOME/.bash_history,如果该文件不存在则新建一个。
10. $IFS:指定Shell脚本中的字段分隔符
$IFS是一个特殊变量,用于指定Shell脚本中的字段分隔符。字段分隔符是将一行输入或输出按照不同的字段拆分开来并存储在不同的变量中的标记。
默认情况下,$IFS的值为空格,制表符和换行符。但是,我们可以将其设置为其他的分隔符来满足特定的需求。
以下是一个示例脚本 test.sh
,它使用$IFS变量来指定不同的分隔符,将一行输入按照分隔符分成不同的变量:
#!/bin/bashecho "Enter a line of values separated by commas (','):"
read lineecho "Default IFS values: '$IFS'"
IFS=","
echo "Custom IFS value set to: '$IFS'"echo "Values entered:"
for value in $line
doecho "$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个特殊变量,总结如下:
特殊变量 | 功能 |
---|---|
$0 | 当前执行的Shell脚本的文件名 |
$1-$9 | 当前Shell脚本的参数1-9 |
$# | 当前Shell脚本的参数数量 |
$? | 上一次执行的命令的退出状态 |
$* | 所有当前Shell脚本的参数,作为一个单独的字符串 |
$@ | 所有当前Shell脚本的参数,作为多个独立的字符串 |
$! | 上一次在后台运行的任务的进程ID |
$$ | 当前Shell脚本的进程ID |
$- | 当前Shell使用的选项(标志) |
$IFS | Shell脚本中用于指定字段分隔符的值 |