Linux中set命令简介
1. 概述
**在本教程中,我们将讨论 Linux 中的set 命令及其用例。我们还将看到它提供的一些选项并了解如何使用它们。
2. set命令
我们使用set命令来更改 shell 选项的值并在 Bash 脚本中显示变量 。我们还可以使用它来调试 Bash脚本 、从 shell 脚本中导出值、在程序失败时终止程序以及处理异常。
set命令的格式如下:
$ set [option] [argument]
在这里,我们使用option来设置或取消设置标志,而argument是位置参数。选项标志会影响 Bash 脚本完成任何所需任务的行为方式。
**当我们运行不带任何参数的set命令时,它会返回所有系统设置的列表。**该列表包括所有 shell 变量和函数的名称和值:
$ set
HISTFILE='/root/.ash_history'
HOME='/root'
HOSTNAME='localhost'
IFS=' '
LINENO=''
OLDPWD='/'
OPTIND='1'
PAGER='less' PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
PPID='1'
PS1='\h:\w\$ '
PS2='> '
PS4='+ '
PWD='/root'
SHLVL='3'
TERM='linux'
TZ='UTC-01:00' _='--version'
script='/etc/profile.d/*.sh'
由于列表很长,我们可以使用 Page Up 和 Page Down 键来浏览它。
3. set命令选项
我们有几个选项可以与set命令一起使用。我们将在本节讨论最常见的。
3.1. -e 选项
当查询返回非零状态时,-e 标志会停止脚本。它还检测当前正在执行的脚本中的错误。
让我们编写一个 Bash 脚本来显示文件的内容,并在该文件存在于我们的目录中时输出一条消息:
#!/bin/bash
set -e
mkdir newfolder
cat filenotindirectory
echo 'The file is not in our directory!'
我们运行可执行文件来测试*-e*标志:
$ chmod u+x eflag.sh
$ ./eflag.sh
cat: can't open 'filenotindirectory': No such file or directory
当脚本试图显示文件filenotindirectory的内容时,由于文件不存在而出错,并立即退出。结果,最终的echo命令也没有运行。
3.2. -C 选项
使用-C*标志可确保我们无法覆盖具有相同名称的现有文件*:
$ echo 'An existing file' > myfile
$ set -C
$ echo 'Editing an existing file' > myfile
sh: can't create myfile: File exists
我们创建了一个名为myfile的文件,但是当我们尝试覆盖其内容时发生错误。使用此标志是避免意外覆盖文件的好习惯。
3.3. -f 选项
众所周知,我们可以使用通配符轻松搜索文件,例如*?*、* 或 []。这种方法类似于正则表达式,我们尝试使用模式查找相似的文本。Bash shell 使用我们指定的通配符来生成模式并将它们与文件名匹配。此功能称为通配符。
让我们通过搜索扩展名为*.txt的文件*来使用通配符:
$ ls *.txt
files.txt
我们可以看到有一个文件带有*.txt*扩展名。
接下来,让我们运行set -f命令,然后使用通配符搜索扩展名为*.txt*的文件:
$ set -f
$ ls *.txt
ls: *.txt: No such file or directory
我们现在得到一个错误作为输出。-f阻止我们使用通配符来搜索文件名或字符串。
我们应该注意,在不指定任何通配符模式的情况下运行ls命令仍然会输出我们目录中所有文件的输出。
3.4. -x 选项
我们在调试脚本时使用-x 参数来确定单个命令的输出。**
为了说明,让我们创建一个显示从 3 到 0 的倒计时的 Bash 脚本:
#!/bin/bash
set -x
n=3
while [ $n -gt 0 ]; do
n=$[ $n-1 ]
echo $n
sleep 1
done
然后,我们执行脚本:
$ bash debugging.sh
+ n=3
+ '[' 3 -gt 0 ']'
+ n=2
+ echo 2
2
+ sleep 1
+ '[' 2 -gt 0 ']'
+ n=1
+ echo 1
1
+ sleep 1
+ '[' 1 -gt 0 ']'
+ n=0
+ echo 0
0
+ sleep 1
+ '[' 0 -gt 0 ']'
我们可以看到代码一次执行一行,在移动到下一行之前显示结果。
3.5. -a 选项
我们可以使用这个标志导出变量或函数,使它们在子shell或脚本中可重用。首先,让我们在终端中定义变量:
$ set -a
$ name='May'
$ age=22
接下来,我们编写一个脚本:
#!/bin/bash
echo $name $age
最后,让我们运行脚本:
$ bash export.sh
May 22
我们可以在上面看到脚本输出创建的变量,由echo命令确定。
或者,我们也可以按照以下顺序运行此set命令:
$ name='May'
$ age=22
接下来,我们编写脚本:
#!/bin/bash
echo $name $age
最后,我们运行脚本:
$ bash export.sh -a
May 22
3.6. -u 选项
我们使用这个标志来确保 Bash 不会忽略我们脚本中不存在的变量。我们可以看到,在正常情况下,Bash 会忽略未分配的变量并运行我们的脚本而没有任何错误:
#!/bin/bash
x='Bash scripting is fun'
echo $x $y
让我们将脚本设为可执行文件,然后运行它:
$ chmod u+x testfile.sh
$ ./testfile.sh
Bash scripting is fun
现在,我们应用带有*-u选项的set*命令:
#!/bin/bash
set -u
x='Bash scripting is fun'
echo $x $y
让我们重新运行脚本:
$ ./testfile.sh
./testfile.sh: line 4: y: unbound variable
我们看到我们得到了一个错误。-u选项防止 Bash 忽略不存在的变量。
3.7. +[argument]选项
使用+[argument] 选项运行set命令会取消设置该选项的功能**。从本质上讲,它使*-[argument]*选项的效果无效。
我们将看到一些使用*set +[argument]*命令及其输出运行的 shell 脚本示例。
首先,我们考虑 set +e:
#!/bin/bash
set +e
mkdir newfolder
cat filenotindirectory
echo 'The file is not in our directory!'
现在,让我们将脚本设为可执行文件并运行它:
$ chmod u+x test.sh
$ ./test.sh
cat: filenotfoundindirectory: No such file or directory
The file is not in our directory!
Bash 脚本输出错误并继续打印 echo 命令。
接下来是set +C选项。首先,我们将内容添加到一个名为 myfile 的新文件中:
$ echo 'An existing file' > myfile
$ ls
eflag.sh myfile
接下来,我们尝试覆盖现有的myfile:
$ set +C
$ echo 'Editing an existing file' > myfile
localhost:~# ls
eflag.sh myfile
我们注意到我们可以覆盖现有文件。
第三,我们考虑set +f选项:
$ set +f
$ ls *.txt
files.txt
通过运行此命令,我们可以使用通配符模式搜索文件。
接下来是 set +x选项:
#!/bin/bash
set +x
n=3
while [ $n -gt 0 ]; do
n=$[ $n-1 ]
echo $n
sleep 1
done
让我们执行脚本:
$ chmod u+x debuggingflag.sh
$ bash debuggingflag.sh
2
1
0
我们根据sleep命令设置的速度查看输出,但是如果我们在代码中遇到错误,输出将不会显示任何调试消息。
最后,我们观察 set +a命令:
$ set +a
$ name=’May’
$ age=22
让我们创建一个回显变量的脚本:
#!/bin/bash
echo $name $age
现在,我们运行我们的脚本:
$ bash export.sh
我们得到一个空输出,因为export.sh 文件中的变量没有赋值。