据我了解,以下内容应test
在 tcsh 中的标准错误上发送“ ”:
echo test >&2
然而,它却将“ test
”写入名为的文件中2
,当我查看历史记录时,我发现实际执行的是
echo test > & 2
我不确定哪一层插入了这些空格,但我能以某种方式阻止它吗?如果不行,我想我可以改用> /dev/stderr
。
答案1
关于csh
,来自http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/:
同样,您不能将 csh 脚本中的错误消息直接发送到 stderr,这被认为是正确的。在 Bourne shell 中,您可能会说:
echo "$0: cannot find $file" 1>&2
但是在 csh 中,您无法将 stdout 重定向出 stderr,因此您最终会做一些愚蠢的事情,例如:
sh -c 'echo "$0: cannot find $file" 1>&2'
我对进行了一些快速尝试tcsh
,并且正如怀疑的那样,它似乎也确实如此(tcsh
应该与完全兼容csh
)。
回答你提出的问题:这无所谓如果您可以tcsh
不“插入空格”,因为无论如何它都不会按照预期的方式解释该序列。
答案2
编辑:
我没看到这是 tsch。请参阅“输入/输出”部分man tsch
了解详细信息,包括以下内容:
诊断输出可通过标准输出的管道进行定向。只需使用 |& 形式,而不只是 |。
目前,shell 无法在不重定向标准输出的情况下重定向诊断输出,但 (command > output-file) >& error-file 通常是一种可接受的解决方法。output-file 或 error-file 可以是 /dev/tty,用于将输出发送到终端。
答案3
Daniel Andersson 的解决方案很棒,如果您要运行的命令可以从 sh 运行(因此,子 shell 将无法更改目录或修改当前 shell 的环境),那么它将非常有效。如果您想将 stdout 转换为 stderr,但将命令执行保留在当前 shell 中,则可以仅使用 bash 进行 stdout 到 stderr 的重定向,如下所示:
echo “错误消息” | bash -c “cat - 1>&2”
答案4
我做了一些实验,尝试在 tcsh 脚本中将标准输出和标准错误定向到 /dev/stderr。我的目的是让脚本的用户能够(也在 tcsh 中)将标准输出和标准错误定向到不同的地方。我发现脚本必须看起来像:
echo 1abc
echo 1ABC >>& /dev/stderr
echo 2abc
echo 2ABC >>& /dev/stderr
如果不使用 >>,则在重定向的脚本输出中,您会丢失一些标准输入和/或标准输出数据。即便如此,使用简单的 >& 将脚本的输出重定向到文件也不是工作;它也会丢失部分标准错误(即使在 bash 上)。你必须用一个
(SCRIPT >! file.out ) >&! file.err
构造。此处,一个文件或两个文件都可以是 /dev/tty,用于输出到屏幕。(如果您不重定向脚本输出,则永远不会有问题。)
请注意,如果您从程序内部指向标准错误,则不会发生任何奇怪的事情。
还请注意,这是在 Linux 上(准确地说是 Ubuntu-MATE LTS 16.04)。当然,您至少需要 /dev/stderr 存在才能使用上述内容。
发布此帖后,我发现了另一个问题。如果你将一个写入标准错误的程序放在 1ABC 行之后,那么如果你将标准错误定向到文件,1ABC 就会丢失。好消息是,在我的情况下,标准错误必须继续转到 /dev/tty。哎呀。:)
为了便于修改,以及没有 /dev/stderr 的系统,我决定通过以下两个标题行来实现这一点
alias stderr echo ; if (-ew /dev/stderr) alias stderr 'echo \!* >> /dev/stderr'
which echo_err > /dev/null ; if !($status) alias stderr echo_err
这允许用户放置一个 sh 脚本 echo_err,
#!/bin/sh
echo $* 1>&2
如果确实需要无错误的标准错误重定向(以两次图像激活为代价),则在路径中。
另一个补充:我上面的帖子是关于在 tcsh 中重定向到 /dev/stderr 的问题。但只要我给出别名,也许我还应该为 Glen Ragan 的解决方案提供一个别名,如果你不介意图像激活的话,这真的非常好。定义
alias 1to2 '\!* | sh -c "cat 1>&2"'
alias 2to1 '\!* |& cat'
然后,您可以在任何希望将标准输出重定向到 stdout 的命令前加上 1to2。这就像在其他 shell(包括 DOS)中在命令前加上 1>&2 一样。而且它在 Linux 中没有错误。那么也可以有一个 2to1。:)
OOPS:上面的 1to2 中有一个小缺陷:如果命令同时写入标准输出和标准错误,则顺序是错误的。在最终的标准错误结果中,命令的标准错误内容最终位于其标准输出内容之前。解决方案很简单;将 | 改为 |&:
alias 1to2 '\!* |& sh -c "cat 1>&2"'
对于那个很抱歉。