为什么我的输出转到stdout而不是文件?

时间:2017-09-14 22:42:33

标签: bash

我有一个这样的脚本:

#!/usr/bin/bash
COMMAND='some_command >> some_log_file 2>&1'
until $COMMAND; do
    echo "some_command crashed with exit code $?.  Respawning.." >&2
    sleep 1
done

(我从https://stackoverflow.com/a/697064/88821获得until ... done位,FWIW,但稍微改了一下。)

正在运行some_command时,问题是输出不会转到some_log_file。相反,它转到我运行此包装脚本的shell的stdout。如何在将整个命令(包括重定向)保留在变量some_log_file中的同时将输出转到COMMAND?我们的想法是将此脚本用作可以与其他程序一起使用的更通用的包装脚本。 (COMMAND 实际作为参数传递到脚本中。)

2 个答案:

答案 0 :(得分:1)

您将>> some_log_file 2>&1 作为some_command 的参数传递,而不是将其视为重定向。发生这种情况是因为在执行参数扩展之前解析shell语法(例如重定向)(处理中$foo被相关变量的内容替换的点)。这实际上是理想的行为 - 否则就不可能在shell中编写处理不受信任数据的代码。

不要将代码存储在字符串中。您可以按字面意思包含它:

until some_command >> some_log_file 2>&1; do
    echo "some_command crashed with exit code $?.  Respawning.." >&2
    sleep 1
done

...或者您可以将其存储在一个函数中:

mycode() { some_command >> some_log_file 2>&1; }

until mycode; do
    echo "some_command crashed with exit code $?.  Respawning.." >&2
    sleep 1
done

答案 1 :(得分:0)

一种方法是

#!/usr/bin/bash
COMMAND='some_command >> some_log_file 2>&1'
until bash -c "$COMMAND"; do
    echo "some_command crashed with exit code $?.  Respawning.." >&2
    sleep 1
done

您的方法存在的问题是它不会将变量评估为bash代码,而是将其作为一系列文字字符串。这就像在不调用Java解释器的情况下将"1+1"置于Java字符串中永远不会导致2打印:

String cmd="1+1";
System.out.println(cmd);  // Prints 1+1
System.out.println(1+1);  // Prints 2