IO重定向

nohup python launch.py --language zh-CN --port 7865 --listen >/dev/null 2>&1 &

在Linux或者Unix中有三个默认打开的文件描述符(file-descriptor),分别是:

  • stdin(标准输入,键盘),其文件描述符是0
  • stdout(标准输出,屏幕),其文件描述符是1
  • stderr(标准错误,屏幕),其文件描述符是2

输出重定向基本语法: Bash输出重定向基本语法

  • 重定向源:一般可以是命令、代码块等;比如echo "Welcome to Jartap"
  • 重定向范围:可已选择标准输出1、标准错误2、或者使用&表示同时重定向标准输出和标准错误;&只有在Bash4.0以上版本才支持;&和重定向方式>>>之间不能有空格
  • 重定向方式:有>>>两种方式,>表示覆盖重定向,>>表示追加重定向
  • 重定向目标:可以是文件、管道、设备等;比如/dev/null 看一些示例:
     COMMAND_OUTPUT > filename # 重定向标准输出到一个文件. 如果文件不存在则创建,否则覆盖.
     ls -lR > dir-tree.list # 创建了一个包含目录树列表的文件.
    
     : > filename
        # ">" 清空了文件.
        # 如果文件不存在,则创建了个空文件 (效果类似 'touch').
        # ":" 是个虚拟占位符, 不会有输出.
    
     > filename    
        # ">" 清空了文件.
        # 如果文件不存在,则创建了个空文件 (效果类似 'touch').
        # (结果和上述的 ": >" 一样, 但在某些 shell 环境中不能正常运行.)
    
     COMMAND_OUTPUT >>
        # 重定向标准输出到一个文件.
        # 如果文件不存在则创建,否则新内容在文件末尾追加.
    
    
        # 单行重定向命令 (只作用于本身所在的那行):
        # --------------------------------------------------------------------
    
     1>filename
        # 以覆盖的方式将 标准错误 重定向到文件 "filename."
     1>>filename
        # 以追加的方式将 标准输出 重定向到文件 "filename."
     2>filename
        # 以覆盖的方式将 标准错误 重定向到文件 "filename."
     2>>filename
        # 以追加的方式将 标准错误 重定向到文件 "filename."
     &>filename
        # 以覆盖的方式将 标准错误 和 标准输出 同时重定向到文件 "filename."
        # 在 bash 4 中才有这个新功能.
    
     M>N
       # "M" 是个文件描述符, 如果不明确指定,默认为 1.
       # "N" 是个文件名.
       # 文件描述符 "M" 重定向到文件 "N."
     M>&N
       # "M" 是个文件描述符, 如果不设置默认为 1.
       # "N" 是另一个文件描述符.
    
        #==============================================================================
    
        # 重定向 标准输出,一次一行.
        LOGFILE=script.log
    
        echo "This statement is sent to the log file, \"$LOGFILE\"." 1>$LOGFILE
        echo "This statement is appended to \"$LOGFILE\"." 1>>$LOGFILE
        echo "This statement is also appended to \"$LOGFILE\"." 1>>$LOGFILE
        echo "This statement is echoed to stdout, and will not appear in \"$LOGFILE\"."
        # 这些重定向命令在每行结束后自动"重置".
    
    
    
        # 重定向 标准错误,一次一行.
        ERRORFILE=script.errors
    
        bad_command1 2>$ERRORFILE       #  Error message sent to $ERRORFILE.
        bad_command2 2>>$ERRORFILE      #  Error message appended to $ERRORFILE.
        bad_command3                    #  Error message echoed to stderr,
                                        #+ and does not appear in $ERRORFILE.
        # 这些重定向命令每行结束后会自动“重置”.
      #=======================================================================
    

输入重定向基本语法:


查询文件描述符

lsof -p <pid>
ls -l /proc/<pid>/fd
ps -ef|grep <pid>

exec和IO重定向

代码块和IO重定向

嵌入文档

嵌入文档(Here Document)简称为Heredoc,是Bash shell中的一个特性,它允许用户将多行文本或命令块作为输入传递给另一个命令。是一种在shell脚本中定义多行输入的方法。它使用特殊的重定向符号«和一个分隔符(通常是字符串,如EOF、END或任何其他自定义字符串)来标识多行文本的起始和结束。其基本语法:

COMMAND <<DELIMITER  
多行文本或命令块  
DELIMITER

看一个示例:

#!/bin/bash
cat <<End-of-message
-------------------------------------
This is line 1 of the message.
This is line 2 of the message.
This is line 3 of the message.
This is line 4 of the message.
This is the last line of the message.
-------------------------------------
End-of-message

# 和以下代码效果相同
echo "-------------------------------------
This is line 1 of the message.
This is line 2 of the message.
This is line 3 of the message.
This is line 4 of the message.
This is the last line of the message.
-------------------------------------" | cat

除了使用<<还可以使用<<-,«和«-的区别在于,«-会忽略开头的制表符(不会忽略空格),而«不会。

#!/bin/bash
cat <<End-of-message
-------------------------------------
	This is line 1 of the message.
    This is line 2 of the message.
This is line 3 of the message.
This is line 4 of the message.
This is the last line of the message.
-------------------------------------
End-of-message

可替换参数

嵌入文档支持参数替换和命令替换,同时支持反斜杠转义,但是不支持通配符扩展,双引号和单引号也失去语法作用,变成了普通字符。 以下示例文件名为test.sh

#!/bin/bash
cat <<End-of-message
-------------------------------------
This is line 1 of the message."$1"
This is line 2 of the message.'$1'
This is line 3 of the message.$1
This is line 4 of the message. `date`
This is the last line of the message. $(date)
-------------------------------------
End-of-message

执行脚本./test.sh查看输出结果,三处$1都被替换了,但是引号没有被去除。命令替换也被正确解析。

灵活的命令替换
variable=$(cat <<SETVAR
This variable
runs over multiple lines.
SETVAR
)

echo "$variable"
禁用参数替换和转义

在嵌入文档使用引号或者\禁用参数替换和转义:

#!/bin/bash
# 使用"、'、\效果是等价的
#cat <<"End-of-message"
#cat <<'End-of-message'
cat <<\End-of-message
-------------------------------------
This is line 1 of the message."$1"
This is line 2 of the message.'$1'
This is line 3 of the message.$1
This is line 4 of the message. `date`
This is the last line of the message. $(date)
-------------------------------------
End-of-message

Here String

嵌入文档还有个变种,称作Here String,其格式cat <<< string

cat <<< "This is a string."
# 其等价于
echo 'This is a string.' | cat
# 如果需要输出引号则需要进行转义

应用程序和重定向