Linux基础知识笔记
介绍
记录linux基础知识,持续更新中…
/dev/null作用
/dev/null
是一个特殊的设备文件,可以将数据重定向到这个文件中,从而实现将输出或错误信息丢弃的效果。在 Linux 系统中,/dev/null
被称为“黑洞”,因为所有写入它的数据都会被立即丢弃,无法恢复。
在 Shell 脚本中,可以使用 >
符号将输出重定向到 /dev/null
,如下所示:
command > /dev/null
这条命令会将 command
命令的输出重定向到 /dev/null
中,从而丢弃所有输出信息。
2>&1作用
2>&1
是将标准错误输出重定向到标准输出的语法。具体来说,2>&1
的含义是将标准错误输出(文件描述符为 2)重定向到标准输出(文件描述符为 1)所指向的目标文件中。在 Shell 脚本中,如果希望将标准错误输出和标准输出输出到同一个文件中,可以使用以下语法:
command > file 2>&1
这条命令会将 command
命令的标准输出和标准错误输出都重定向到 file
文件中。注意,2>&1
必须放在 >
符号的后面,否则会出现语法错误。
执行.sh脚本
执行sh脚本时前面需要加上‘./’
在Unix和类Unix系统中,当执行一个脚本文件时,如果你直接输入脚本文件名而不包含路径,系统会在当前目录(.
)和系统的PATH环境变量指定的目录中查找该文件。如果系统找不到该文件,就会出现“command not found”的错误。
为了确保系统在当前目录中查找脚本文件,你需要在脚本文件名前加上./
。这个./
告诉系统你正在指定一个相对路径,即相对于当前工作目录的路径。
例如,如果你的脚本文件名为script.sh
,并且它位于当前目录中,你需要使用以下命令来执行它:
./script.sh
如果没有./
,系统会尝试在PATH中查找名为script.sh
的命令,而不是在当前目录中查找名为script.sh
的文件。
在执行脚本文件时加上./
有以下几个原因:
-
明确指定当前目录:
./
告诉系统你正在指定一个相对于当前目录的路径,这样系统就不会在PATH中查找该文件,而是在当前目录中查找。 -
避免PATH中的同名命令:如果PATH中有同名的命令,使用
./
可以确保执行的是当前目录中的脚本文件,而不是PATH中的命令。 -
脚本文件的可移植性:使用
./
可以确保脚本在不同的目录中执行时都能正确找到脚本文件,而不管当前的工作目录是什么。 -
避免权限问题:如果脚本文件没有执行权限,加上
./
可以确保脚本以当前用户的权限执行,而不是因为权限问题而无法执行。
#!/bin/bash和 #!/usr/bin/env bash的区别
#!/bin/bash
和 #!/usr/bin/env bash
都是脚本文件的shebang行,用于指定脚本应该使用哪个shell解释器来执行。它们之间的主要区别在于如何指定解释器的位置。
-
#!/bin/bash
直接指定了bash解释器的绝对路径。这种方法的优点是它是确定的,不会因为系统环境变量的变化而变化。但是,如果bash的路径在某些系统上有所不同,或者bash不在默认的/bin
目录中,那么这种方法可能会失败。 -
#!/usr/bin/env bash
使用了env
命令,它会在环境变量PATH
中查找bash
命令。这种方法的好处是它会根据系统的环境变量来确定bash的位置,这样可以确保在不同的系统上都能找到正确的bash解释器。
在大多数情况下,#!/usr/bin/env bash
是一种更好的选择,因为它更具可移植性。然而,如果你的脚本需要在所有系统上都使用相同的bash版本,那么使用 #!/bin/bash
可能会更可靠。
例如,如果你在一个系统上有一个特定的bash版本,并且你知道这个版本的路径是 /opt/special/bash
,那么你应该使用 #!/bin/bash
来确保你的脚本在所有系统上都能使用这个特定的bash版本。
#!/bin/bash
# Your script here
而如果你希望你的脚本在大多数系统上都能正常工作,那么你应该使用 #!/usr/bin/env bash
,因为它会根据系统的环境变量来确定bash的位置。
#!/usr/bin/env bash
# Your script here
sh命令执行.sh脚本和直接执行.sh脚本的区别
使用 sh
命令执行 .sh
脚本和直接执行 .sh
脚本的主要区别在于如何读取和解释脚本文件。
-
解释器指定:
- 如果脚本文件的第一行是
#!/bin/bash
或者#!/usr/bin/env bash
,那么直接执行脚本时,sh
命令会忽略这一行,因为sh
默认使用sh
解释器。 - 如果脚本文件的第一行是
#!/bin/sh
或者#!/usr/bin/env sh
,那么直接执行脚本时,sh
命令会使用sh
解释器来执行脚本。
- 如果脚本文件的第一行是
-
环境变量:
- 直接执行脚本时,脚本继承了当前 shell 的环境变量。
- 使用
sh
命令执行脚本时,脚本会启动一个新的 shell 进程,因此脚本会继承sh
命令的环境变量,而不是当前 shell 的环境变量。
-
脚本行为:
- 如果脚本使用了 bash 特有的语法或功能,直接执行脚本可能会因为
sh
解释器不支持这些特性而失败。 - 使用
sh
命令执行脚本时,如果脚本使用了 bash 特有的语法或功能,sh
命令会尝试忽略这些特性,以确保脚本在sh
解释器下正常运行。
- 如果脚本使用了 bash 特有的语法或功能,直接执行脚本可能会因为
-
性能:
- 直接执行脚本通常比使用
sh
命令执行脚本稍微快一些,因为它避免了启动一个新的 shell 进程的开销。
- 直接执行脚本通常比使用
-
可移植性:
- 使用
sh
命令执行脚本通常比直接执行脚本更可移植,因为它确保了脚本在不同的 shell 环境中都能正确运行。
- 使用
在大多数情况下,直接执行脚本应该就足够了,除非你需要确保脚本在 sh
解释器下运行,或者你需要脚本继承当前 shell 的环境变量。如果你的脚本需要 bash 特有的功能,或者你希望确保脚本在 sh
解释器下运行,那么使用 sh
命令执行脚本是一个好主意。
例如,如果你有一个脚本,它使用了 bash 的 [[
条件测试语法,并且你希望确保它在所有类型的 shell 下都能正确运行,那么你应该使用 sh
命令来执行脚本:
#!/bin/bash
# 使用 bash 特有的 [[ 条件测试语法
# 使用 sh 命令执行脚本
sh myscript.sh
在这个例子中,即使 myscript.sh
使用了 bash 特有的语法,使用 sh
命令执行脚本可以确保脚本在 sh
解释器下正常运行,即使 sh
解释器不支持 bash 的所有特性。