tcshでstdoutをstderrにリダイレクトします


4

私の理解では、以下はtesttcshの標準エラーで' 'を送信するはずです。

echo test >&2

ただし、代わりに「test」という名前のファイルに「」を書き込み2、履歴を見ると、実際に実行されたのは

echo test > & 2

どのレイヤーがそれらのスペースを挿入しているのかわかりませんが、どうにかして停止できますか?そうでない場合は、常に> /dev/stderr代わりに使用できると思います。


echo test >&2stderrに出力します。少なくとも私のbashでは。
デアホッホステープラー

1
ところで、>シェルインジケーターとして使用すると、現在のコンテキストのコードスニペットでかなり混乱します;)
Der Hochstapler

1
最初はbashも想定していましたが、tschというタグが付いています。
デイブフォーガック

1
混乱して申し訳ありません。うまくいけば私の質問がもっと明確になります。ここでbashを使用できれば、それが私にとってはうまくいくので、そうします。
ネイトパーソンズ

リダイレクトを引用してもらえますか?echo test '>&2'?それが機能するかどうかはわかりません。試してみるtcshがありません。
kevlar1818

回答:


5

についてcshhttp://www.faqs.org/faqs/unix-faq/shell/csh-whynot/ から:

これらと同じ線に沿って、適切と考えられるように、エラーメッセージをcshスクリプトでstderrに送信することはできません。Bourneシェルでは、次のように言うことができます。

echo "$0: cannot find $file" 1>&2

しかし、cshでは、stdoutをstderrにリダイレクトできないため、次のような愚かなことをすることになります。

sh -c 'echo "$0: cannot find $file" 1>&2'

私はを使っていくつかの簡単な試行を行いましたがtcsh、疑いがあるように、それも同様に当てはまるようです(tcshと完全に互換性があるはずcshです)。


作成された質問に対処するには、「スペースを挿入しない」ようにすることができるかどうかは関係ありtcshません。とにかくそのシーケンスを意図した方法で解釈しないからです。


5

編集:

これがtschだとは思いませんでした。man tschこれを含む詳細については、「入出力」セクションを参照してください。

診断出力は、標準出力のパイプを介して送信できます。単に|ではなく、フォームを使用してください。

シェルは現在、標準出力もリダイレクトせずに診断出力をリダイレクトできませんが、(コマンド>出力ファイル)>&エラーファイルは多くの場合、許容できる回避策です。出力ファイルまたはエラーファイルは、端末に出力を送信するために/ dev / ttyになります。


2
それを指摘してくれてありがとう。プロセスの診断出力(stderr?)をリダイレクトしたくないので、代わりに通常の出力をstdoutに表示します。
ネイトパーソンズ

@drhorrible:それは本質的に同じことです。あなたがしているのは、echoプロセスを開始し、その出力をstderrにリダイレクトすることです。したがって、stderrへの効果的な印刷:)
Der Hochstapler

それはうまくいかないようです。(echo test > out) >& err「out」というファイルに「test」を書き込み、少なくとも私のマシン上に空のファイル「err」を作成します。
ネイトパーソンズ

これは、両方に出力を送信するコマンドから取得STDOUTしてSTDERR分割し、それらをファイルに送信するための良い方法です。 ただし、tcsh で(echoが出力を送信する)を強制する方法に関するOPの質問に答えませSTDOUTSTDERR
ランドール

3

Daniel Anderssonのソリューションは優れており、実行したいコマンドをshから実行できる場合はうまく機能します(したがって、ディレクトリを変更したり、現在のシェルの環境を変更したりできないサブシェル)。stdoutをstderrに変換し、現在のシェルでコマンドの実行を維持する場合は、次のようにstdoutからstderrへのリダイレクトにのみbashを使用できます。

echo "エラーメッセージ" | bash -c "cat-1>&2"


1

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のないシステムを可能にするために、次の2つのヘッダー行を使用してこれを実装することにしました。

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

バグのない標準エラーのリダイレクトが本当に必要な場合は、パスで(2つのイメージのアクティブ化を犠牲にして)。

別の追加:上記の私の投稿は、tcsh内の/ dev / stderrへのリダイレクトの問題に関するものでした。ただし、エイリアスを提供している限り、Glen Raganのソリューション用のエイリアスも提供する必要があります。これは、イメージのアクティブ化を気にしない場合は非常に便利です。定義する

alias 1to2 '\!* | sh -c "cat 1>&2"'
alias 2to1 '\!* |& cat'

次に、標準出力を1to2でstdoutにリダイレクトするコマンドの前に置くことができます。これは、DOSを含む他のシェルでコマンドの前に1>&2を付けるのと同じように機能します。また、Linuxではバグがありません。2to1もあります。:)

OOPS:上記の1to2の小さな欠陥:コマンドが標準出力と標準エラーの両方に書き込む場合、順序が間違っています。コマンドの標準エラーは、最終的な標準エラーの結果の標準出力よりも先に終了します。解決策は簡単です。変更| に|&:

alias 1to2 '\!* |& sh -c "cat 1>&2"'

ごめんなさい

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.