【问题标题】:Redirecting output from a function block to a file in Linux将功能块的输出重定向到 Linux 中的文件
【发布时间】:2013-08-07 05:15:45
【问题描述】:

就像我们将输出从 for 循环块重定向到文件

for ()
do
  //do something
  //print logs
done >> output file

在 shell 脚本中类似,有没有办法将功能块的输出重定向到文件,像这样?

function initialize {
         //do something
         //print something
} >> output file

//call initialize

如果没有,还有其他方法可以实现吗?请注意我的函数有很多消息要打印在日志中。在每一行将输出重定向到文件会导致大量的 I/O 利用率。

【问题讨论】:

    标签: linux shell unix


    【解决方案1】:

    在调用函数时进行重定向。

    #!/bin/bash
    initialize() {
      echo 'initializing'
      ...
    }
    #call the function with the redirection you want
    initialize >> your_file.log
    

    或者,在函数中打开一个子shell并重定向子shell输出:

    #!/bin/bash
    initialize() {
      (  # opening the subshell
        echo 'initializing'
        ...
      # closing and redirecting the subshell
      ) >> your_file.log
    }
    # call the function normally
    initialize
    

    【讨论】:

    • 我正在尝试做同样的事情,并且对我的函数进行编码,就像在原始问题中一样。 echo 语句存在于函数中,并且在函数的右大括号之后重定向到 stderr。它有效,但我来这里是为了验证这被认为是可以的。调用函数时进行重定向而不是让函数自己执行重定向的原因是什么?
    【解决方案2】:

    您建议的方式实际上是完全有效的。 Bash manual 给出的函数声明语法如下(强调我的)1

    函数使用以下语法声明:

    name () compound-command [ redirections ]

    函数 name [()] compound-command [ redirections ]

    所以这将是完全有效的并将outfile 的内容替换为myfunc 的参数:

    myfunc() {
        printf '%s\n' "$1"
    } > outfile
    

    或者,附加到outfile

    myappendfunc() {
        printf '%s\n' "$1"
    } >> outfile
    

    但是,即使您可以将目标文件的名称放入变量中并重定向到该变量,如下所示:

    fname=outfile
    
    myfunc() { printf '%s\n' "$1"; } > "$fname"
    

    我认为在调用函数的地方进行重定向会更清晰——就像在其他答案中推荐的那样。我只是想指出您可以将重定向作为函数声明的一部分。


    1这不是 bashism:POSIX Shell spec 还允许在函数定义命令中进行重定向。

    【讨论】:

      【解决方案3】:

      您可以使用exec 进行shell 重定向,不确定它是否适用于函数

      exec > output_file
      function initialize {
        ...
      }
      initialize
      

      【讨论】:

        【解决方案4】:

        我的解决方案是包装函数。

        init_internal(){
          echo "this is init_internal with params: $@"
          echo "arg1 $1"
          echo "arg2 $2"
        }
        
        init() {
          local LOG_PATH=$1
          echo "LOG at: $LOG_PATH"
          init_internal "${@:2}" > ./$LOG_PATH 2>&1
        }
        
        init log.log a b c d
        
        cat ./log.log
        

        它输出:

        LOG at: log.log
        this is init_internal with params: a b c d
        arg1 a
        arg2 b
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-01
          • 2012-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-22
          • 1970-01-01
          相关资源
          最近更新 更多