免责声明
蟹堡安全团队的技术文章仅供参考,任何个人和组织在使用网络时应当遵守相关法律法规,不得利用网络从事危害国家安全、荣誉和利益的活动。未经授权,请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责,蟹堡安全团队及文章作者不承担任何责任。本文所提供的工具仅用于学习,禁止用于其他用途!
Before a command is executed, its input and output may be
redirected using a special notation interpreted by the shell.
Redirection allows commands' file handles to be duplicated,
opened, closed, made to refer to different files, and can
change the files the command reads from and writes to.
Redirection may also be used to modify file handles in the
current shell execution environment. The following redirection
opera‐tors may precede or appear anywhere within a simple
command or may follow a command. Redirections are processed
in the order they appear,from left to right.
Google翻译:在执行命令之前,可以使用 shell 解释的特殊符号重定向其输
入和输出。重定向允许复制、打开、关闭命令的文件句柄,使其引用不同的文件,
并可以更改命令读取和写入的文件。重定向还可用于修改当前 shell 执行环境中
的文件句柄。以下重定向运算符可以位于简单命令之前或内部任何位置,也可以位
于命令之后。重定向按其出现的顺序从左到右进行处理。
01
Each redirection that may be preceded by a file descriptor
number may instead be preceded by a word of the form
{varname}. In this case, for each redirection operator
except >&- and <&-, the shell will allocate a file descriptor
greater than or equal to 10 and assign it to varname. If
>&- or <&- is preceded by {varname}, the value of varname
defines the file descriptor to close. If {varname} is
supplied, the redirection persists beyond the scope of the
command, allowing the shell programmer to manage the file
descriptor himself.
Google翻译:每个重定向前面可以有一个文件描述符编号,但也可以以
{varname} 形式的单词开头。在这种情况下,对于除 >&- 和 <&- 之外的每个重
定向运算符,shell 将分配一个大于或等于 10 的文件描述符并将其分配给
varname。如果 >&- 或 <&- 前面有 {varname},则 varname 的值定义要关闭
的文件描述符。如果提供了 {varname},则重定向将超出命令的范围,从而允许
shell 程序员自己管理文件描述符。
使用
exec {fd}<>demo.txt
打开一个文件描述符fd,用于将流指向当前路径下的demo.txt文件(如果文件不存在将会在指定路径下创建对应的文件)。
通过
echo "Hello world!" >& ${fd}
将"Hello world!"数据流写入上面定义的文件描述符fd,
通过前后两次通过cat查看demo.txt中的文本内容可以发现,"Hello world!"数据成功通过流的形式写入文件描述符fd所指向文件。
针对shell 将分配一个大于或等于 10 的文件描述符并将其分配给 varname,我们可以采用ls命令查看所有的文件描述符。
ls -l /proc/$$/fd
在上述命令中我们可以通过前后对比看到,在创建完文件描述符fd后,生成了一个文件描述符编号为10的文件描述符,指向我们所指定的demo.txt这个文件。
可以通过以下命令在文件描述符产生影响后删除对应的文件描述符
exec {fd}>&-
上述过程中我们已经通过对应命令删除了fd文件描述符,在删除后继续向fd文件描述符中输入内容,就会发生下面的错误。
$: echo "Hello world!" >& ${fd}
bash: ${fd}: Bad file descriptor
bash: ${xx}: Bad file descriptor错误原因
针对上面途中爆出的"bash: ${fd}: Bad file descriptor" 这个错误表明你尝试使用一个已经关闭或者无效的文件描述符(file descriptor)进行操作。当你看到这个错误时,可能是由于以下几个原因:
-
文件已关闭:尝试对已经关闭的文件描述符进行操作时,系统会返回这个错误。
-
文件描述符无效:如果使用了无效的文件描述符,系统也会返回这个错误。
-
权限问题:如果没有足够的权限来打开或读取文件,系统会返回这个错误。
特殊的文件描述符
Bash handles several filenames specially when they are used
in redirections, as described in the following table. If the
operating system on which bash is running provides these special
files, bash will use them; otherwise it will emulate them
internally with the behavior described below.
/dev/fd/fd
If fd is a valid integer, file descriptor fd is
duplicated.
/dev/stdin File descriptor 0 is duplicated.
/dev/stdout File descriptor 1 is duplicated.
/dev/stderr File descriptor 2 is duplicated.
/dev/tcp/host/port
If host is a valid hostname or Internet address, and
port is an integer port number or service name, bash
attempts to open the corresponding TCP socket.
/dev/udp/host/port
If host is a valid hostname or Internet address, and
port is an integer port number or service name, bash
attempts to open the corresponding UDP socket.
A failure to open or create a file causes the redirection to
fail.Redirections using file descriptors greater than 9 should
be used with care, as they may conflict with file descriptors
the shell uses internally.
Note that the exec builtin command can make redirections
take effect in the current shell.
Google翻译:Bash 在重定向中使用多个文件名时会对其进行特殊处理,如下
表所述。如果运行 bash 的操作系统提供了这些特殊文件,bash 将使用它们;
否则它将在内部使用下述行为模拟它们。
/dev/fd/fd 如果 fd 是有效整数,则文件描述符 fd 被复制。
/dev/stdin 文件描述符 0 用于表示标准输入,通常是键盘输入。
程序可以从标准输入读取数据。
/dev/stdout 文件描述符 1 用于表示标准输出,通常是终端或控制台输出
程序可以将数据写入标准输出。
/dev/stderr 文件描述符 2 用于表示标准错误输出,通常也是终端或控制
台。程序可以将错误信息写入标准错误。
/dev/tcp/host/port 如果 host 是有效主机名或 Internet 地址,而
port 是整数端口号或服务名称,则 bash 尝试打开相应的 TCP 套接字。
/dev/udp/host/port 如果 host 是有效主机名或 Internet 地址,而
port 是整数端口号或服务名称,则 bash 尝试打开相应的 UDP 套接字。
打开或创建文件失败会导致重定向失败。使用大于 9 的文件描述符的重定向
应谨慎使用,因为它们可能与 shell 内部使用的文件描述符冲突。
请注意,exec 内置命令可以使重定向在当前 shell 中生效。
02
重定向引用标准符号 In the following descriptions, if the file descriptor number
is omitted, and the first character of the redirection operator
is <, the redirection refers to the standard input (file
descriptor 0). If the first character of the redirection
operator is >, the redirection refers to the standard output (
file descriptor 1).
Google翻译:在下面的描述中,如果省略文件描述符编号,并且重定向操作符的
第一个字符为 <,则重定向指向标准输入(文件描述符 0)。如果重定向操作符的
第一个字符为 >,则重定向指向标准输出(文件描述符 1)。
< 重定向引用标准输入
Redirecting Input
Redirection of input causes the file whose name results from
the expansion of word to be opened for reading on file
descriptor n, or the standard input(file descriptor 0) if
n is not specified.
The general format for redirecting input is:
[n]<word
Google翻译:重定向输入会导致以 word 扩展名作为文件名的文件在文件
描述符 n 上打开以供读取,如果未指定 n,则在标准输入(文件描述符 0)上打
开。
重定向输入的一般格式为:
[n]<word
> 重定向引用标准输出(覆盖)
Redirecting Output
Redirection of output causes the file whose name results
from the expansion of word to be opened for writing on file
descriptor n, or the standard output(file descriptor 1) if n
is not specified. If the file does not exist it is created; if
it does exist it is truncated to zero size.
The general format for redirecting output is:
[ ]>word
Google翻译:重定向输出会导致以 word 扩展名作为名称的文件被打开,以
便在文件描述符 n 上写入,如果未指定 n,则在标准输出(文件描述符 1)上写
入。如果文件不存在,则创建该文件;如果文件存在,则将其截断为零大小。
重定向输出的一般格式为:
[ ]>word
BASH noclobber 变量的作用
noclobber 是 Bash 中的一个选项,它用于防止覆盖已存在的普通文件。当 noclobber 选项被设置时,任何尝试使用 > 重定向操作符将输出覆盖到现有文件的操作都会失败,Bash 会报告一个错误,而不是覆盖文件。
在bash的帮助文档中有下面的这段介绍,
If the redirection operator is >, and the noclobber option to
the set builtin has been enabled, the redirection will fail if
the file whose name results from the expansion of word
exists and is a regular file. If the redirection operator is >|
, or the redirection operator is > and the noclobber option to
the set builtin command is not enabled, the redirection is
attempted even if the file named by word exists.
Google翻译:如果重定向运算符是 >,并且已启用 set 内置命令的
noclobber 选项,则如果由 word 扩展而得名的文件存在且为常规文件,则重定
向将失败。如果重定向运算符是 >|,或者重定向运算符是 > 且 set 内置命令
的 noclobber 选项未启用,则即使由 word 命名的文件存在,也会尝试重定向
。重定向标准输出和标准错误 此构造允许将标准输出(文件描述符 1)和标准错
误输出(文件描述符 2)重定向到名为 word 扩展的文件。
使用
set -o noclobber
这条命令开启noclobber 选项。
在开启noclobber 选项(默认情况下是关闭的)时,我们尝试填充一段数据123来覆盖原本的数据内容1234,执行命令后发现命令写入文件失败,报出错误'cannot overwrite existing file'。
![Bash REDIRECTION 文档详解 Bash REDIRECTION 文档详解]()
这种情况下有两种方式写入文件:
1. 使用>|强制覆盖文件
在bash重定向中可以通过使用 >| 强制覆盖文件
![Bash REDIRECTION 文档详解 Bash REDIRECTION 文档详解]()
2. 关闭noclobber选项
使用
set +o noclobber
这条命令会关闭 noclobber 选项,从而导致允许重定向操作覆盖现有的普通文件。
![Bash REDIRECTION 文档详解 Bash REDIRECTION 文档详解]()
> >重定向引用标准输出(追加)
关于这个符号的介绍就不做过多的解释了,他和>的作用类似,唯一有区别的地方就是它采用的是追加模式。
Redirection of output in this fashion causes the file whose
name results from the expansion of word to be opened for
appending on file descriptor n, or the standard output (file
descriptor 1) if n is not specified. If the file does not exist
it is created.
The general format for appending output is:
[n]>>word
Google翻译:以这种方式重定向输出会导致打开以 word 扩展为名称的文件,
以便在文件描述符 n 上附加,如果未指定 n,则打开标准输出(文件描述符 1)
。如果文件不存在,则会创建该文件。
附加输出的一般格式为:
[n]>>word
03
重定向标准输出和标准错误
This construct allows both the standard output (file
descriptor 1) and the standard error output (file descriptor 2)
to be redirected to the file whose name is the expansion of
word.
There are two formats for redirecting standard output and
standard error:&>word and >&word, Of the two forms, the first is
preferred. This is semantically equivalent to >word 2>&1
When using the second form, word may not expand to a number or
-. If it does, other redirection operators apply (see
Duplicating File Descriptors below) for compatibility
reasons.Appending Standard Output and Standard Error
This construct allows both the standard output (file
descriptor 1) and the standard error output (file descriptor 2)
to be appended to the file whose name is the expansion of word.
The format for appending standard output and standard error
is:
& word
This is semantically equivalent to
2>&1 word
Google翻译:此构造允许将标准输出(文件描述符 1)和标准错误输出(文件
描述符 2)重定向到名称为 word 扩展名的文件。重定向标准输出和标准错误有两
种格式:&>word 和 >&word。这两种形式中,第一种是首选。这在语义上等同
于>word 2>&1使用第二种形式时,word 可能不会扩展为数字或 -。如果是这样,
出于兼容性原因,将应用其他重定向运算符(请参阅下面的复制文件描述符)。
附加标准输出和标准错误此构造允许将标准输出(文件描述符 1)和标准错误输出
(文件描述符 2)附加到名称为 word 扩展名的文件。
附加标准输出和标准错误的格式为:
& word
这在语义上等同于
2>&1 word
&在重定向中的应用
在这里我们以"2>&1" 这个命令为主要参考对象,这条命令的意思是将标准错误(文件描述符 2)重定向到标准输出(文件描述符 1)。这里的 &
符号连接了文件描述符 1,告诉 Bash 将标准错误流复制到标准输出流。
具体来说:
-
2>
表示标准错误(stderr)的重定向。 -
&1
表示将标准错误重定向到文件描述符 1,即标准输出(stdout)。
因此,当你在一个命令后面加上 2>&1
,比如:
ls 2>&1
这个命令会使得 ls命令执行过程中的所有错误输出(原本会发送到标准错误)被重定向到标准输出。
功能扩展
The word following the redirection operator in the following
descriptions, unless otherwise noted, is subjected to brace
expansion, tilde expansion, parameter and variable expansion,
command substitution, arithmetic expansion, quote removal,
pathname expansion, and word splitting. If it expands to more
than one word, bash reports an error.
Google翻译:除非另有说明,否则以下描述中重定向运算符后面的单词将进行括
号扩展、波浪线扩展、参数和变量扩展、命令替换、算术扩展、引号删除、路径名
扩展和单词拆分。如果它扩展为多个单词,bash 将报告错误。
这一节主要告诉我们,在bash执行命令处理数据流的过程中会有哪些特性。
1. Brace Expansion(大括号展开)
允许模式匹配和生成字符串列表。
2. Tilde Expansion(波浪线展开)
将波浪线(~
)替换为当前用户的主目录路径。
3. Parameter Expansion(参数展开)
替换参数(变量)的值。
4. Command Substitution(命令替换)
执行命令并替换为命令的输出。
5. Arithmetic Expansion(算术展开)
执行算术运算并替换结果。
6. Quote Removal(引号去除)
去除单词周最外层引号。
7. Pathname Expansion(路径名展开)
也称为通配符展开,匹配文件名模式。
8. Word Splitting(单词分割)
将单词分割成单词列表。
04
重定向操作顺序
Note that the order of redirections is significant.For example
, the command
ls > dirlist 2>&1
directs both standard output and standard error to the file
dirlist, while the command
ls 2>&1 > dirlist
directs only the standard output to file dirlist, because the
standard error was duplicated from the standard output before
the standard output was redirected to dirlist.
ls > dirlist 2>&1 将标准输出和标准错误都定向到文件 dirlist,
而命令 ls 2>&1 > dirlist 仅将标准输出定向到文件 dirlist,因为在标准输
出重定向到 dirlist 之前,标准错误已从标准输出复制。
这段话的意思是,在 Bash 中执行命令时,重定向操作的顺序是非常重要的。这是因为重定向操作会影响命令的输出和错误流的顺序和目的地。具体来说:
ls > dirlist 2>&1
-
这个命令首先执行
ls
命令。 -
> dirlist
将ls
命令的标准输出(stdout)重定向到文件dirlist
。 -
2>&1
将ls
命令的标准错误(stderr)重定向到标准输出(stdout),而此时的标准输出已经被重定向到dirlist
文件了。 -
结果是,
ls
命令的所有输出(包括错误信息)都会被写入到dirlist
文件中。
ls 2>&1 > dirlist
-
这个命令首先执行
ls
命令。 -
2>&1
将ls
命令的标准错误重定向到标准输出。 -
> dirlist
将ls
命令的标准输出重定向到文件dirlist
。 -
但是,由于
2>&1
在> dirlist
之前执行,所以当> dirlist
执行时,标准输出已经被设置为dirlist
文件,而标准错误已经被重定向到这个新的标准输出(即dirlist
文件)。 -
结果是,
ls
命令的标准输出会被写入到dirlist
文件中,而标准错误也会被写入到同一个dirlist
文件中。
简而言之,重定向的顺序决定了输出和错误流的最终目的地。
05
文档描述符
The format of here-documents is:
[n]<<[-]word
here-document
delimiter
No parameter and variable expansion, command substitution,
arithmetic expansion, or pathname expansion is performed on word
. If any part of word is quoted, the delimiter is the result of
quote removal on word, and the lines in the here-document are
not expanded. If word is unquoted, all lines of the
here-document are subjected to parameter expansion, command
substitution, and arithmetic expansion, the character sequence
<newline> is ignored, and must be used to quote the
characters , $, and `.
If the redirection operator is <<-, then all leading tab
characters are stripped from input lines and the line containing
delimiter. This allows here-documents within shell scripts to be
indented in a natural fashion.
Google翻译:此处文档的格式为:
[n]<<[-]word
此处文档
分隔符
不对 word 执行任何参数和变量扩展、命令替换、算术扩展或路径名扩展。如果
word 的任何部分被引用,则分隔符是 word 上引号删除的结果,并且不会扩展此
处文档中的行。如果 word 未被引用,则此处文档的所有行都将进行参数扩展、命
令替换和算术扩展,字符序列 <newline> 将被忽略,并且必须使用 来引用字
符 、$ 和 `。
如果重定向运算符是 <<-,则所有前导制表符都将从输入行和包含分隔符的行中
删除。这允许以自然方式缩进 shell 脚本中的此处文档。
Here-documents 以 [n]<<[-]word开始,其中 [n]是可选的,表示文件描述符编号;[-]也是可选的,表示关闭 quote removal(引号去除)功能;word是定界符(delimiter),用来标识 here-documents 的结束(可以同比PHP等语言中对于多行字符串的定义)。
这个part最主要的部分是关于<<符号和<<-符号的结果展示的区别。如果使用的是 <<-,则输入行和包含定界符的行中的所有前导制表符(tab)都会被删除。
# 使用 <<- 定界符,前导 tab 会被去除
cat <<- END
This line starts with a tab character.
This line also starts with a tab character.
These lines will be indented in the script but will not have leading tabs in the output.
END
echo "------"
# 使用 << 定界符,前导 tab 不会被去除
cat << END
This line starts with a tab character.
This line also starts with a tab character.
These lines will be indented in the script and will have leading tabs in the output.
END
Here Strings
A variant of here documents, the format is:
[n]<<<word
The word undergoes tilde expansion, parameter and variable
expansion, command substitution, arithmetic expansion, and quote
removal. Pathname expansion and word splitting are not
performed. The result is supplied as a single string, with a
newline appended, to the command on its standard input (or
file descriptor n if n is specified).
Google翻译:Here 文档的变体,格式为:[n]<<<word。word 经过波浪号扩
展、参数和变量扩展、命令替换、算术扩展和引号删除。不执行路径名扩展和单词
拆分。结果作为单个字符串提供给命令的标准输入(或文件描述符 n,如果指定了
n)。
这就是一类很特殊的格式,在流传递过程中不执行路径名扩展和单词拆分。
06
复制文件描述符
The redirection operator [n]<&word is used to duplicate input
file descriptors. If word expands to one or more digits, the
file descriptor denoted by n is made to be a copy of that file
descriptor. If the digits in word do not specify a file
descriptor open for input, a redirection error occurs. If word
evaluates to -, file descriptor n is closed. If n is not
specified, the standard input (file descriptor 0) is used.
Google翻译:重定向运算符 [n]<&word 用于复制输入文件描述符。如果
word扩展为一个或多个数字,则将 n 表示的文件描述符作为该文件描述符的副本
。如果word 中的数字未指定为输入打开的文件描述符,则会发生重定向错误。如
果 word 计算结果为 -,则文件描述符 n 被关闭。如果未指定 n,则使用标准输
入(文件描述符 0)。
在上面的示例中我先尝试使用exec创建一个控制test.txt的流的文件描述符3,随后又使用exec将文件描述符3的流指向赋值给文件描述符4,采用ls命令查看所有的文件描述符,可以发现对于文件描述符3和4,分别都是指向同一个文件的link。
原文始发于微信公众号(蟹堡安全团队):Bash REDIRECTION 文档详解
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论