質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.30%
Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

2回答

545閲覧

Linuxの標準エラー出力のリダイレクトに関する質問

hokuyan

総合スコア2

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

0クリップ

投稿2023/10/12 08:13

編集2023/10/12 08:19

シェルスクリプト内で標準エラー出力をファイルにリダイレクトするコードを作成していたのですが、思ったように動作されていないため、私の認識がずれているかどうか確認したいため質問させていただきます。

#!/bin/bash echo "ERROR: This is error." 1>&2 2> ./sample_out.txt

上記のようなコードについて、エラー出力がファイルにリダイレクトされると思ったのですが、ターミナルに出力されてしまいました。

前提

私の認識が少しずれている気がするので確認いたします。

  • &1 … 現在、標準出力 (1) に割り当てられている出力先
  • &2 … 現在、標準エラー出力 (2) に割り当てられている出力先
  • 1>&2 … 標準出力 (1) の出力先を &2 に切り替える
  • 2>&1 … 標準エラー出力 (2) の出力先を &1 に切り替える

(引用:https://maku77.github.io/p/q2k3j2h/)
このことから「標準エラー出力に出力を行うコマンド」は1>&2であると判断しました。

また、2>はファイル・ディスクリプター2が標準エラー出力として定義されていることから、標準エラー出力をファイルに書き込むリダイレクト方法とありました。
(引用:https://qiita.com/laikuaut/items/e1cc312ffc7ec2c872fc)
実際に、意図的にエラー出力を吐くように作成した結果、エラー出力はリダイレクトされました。
ech "HELLO" 2> sample_out.txt
そのことから、
echo "ERROR: This is error." >&2 2> ./sample_out.txt
とすることで標準エラー出力がファイルにリダイレクトされるものと考えましたが、ターミナルに出力されてしまいました。
一方で
echo "ERROR: This is error." >&2 1> ./sample_out.txt
とするとしっかりファイルにリダイレクトされます。
私の認識のどこが間違っているのか教えていただきたいです。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2023/10/12 08:29

$ echo "ERROR: This is error." >&2 2> ./sample_out.txt >&2 は stdout を「リダイレクト時点での stderr の出力先」に切り替えます。つまり、デフォルトの出力先である terminal(画面)になります。なので、期待する出力を得るには、 echo "ERROR: This is error." 2> ./sample_out.txt >&2 とします。
guest

回答2

0

すでに回答の付いている通りですが、日本語文章の解釈の問題でもありますね。

&1 … 現在、標準出力 (1) に割り当てられている出力先
&2 … 現在、標準エラー出力 (2) に割り当てられている出力先
1>&2 … 標準出力 (1) の出力先を &2 に切り替える
2>&1 … 標準エラー出力 (2) の出力先を &1 に切り替える

1,2行目で定義された &1 &2 を3,4行目の文章に代入すると、

&1 … 現在、標準出力 (1) に割り当てられている出力先
&2 … 現在、標準エラー出力 (2) に割り当てられている出力先
1>&2 … 標準出力 (1) の出力先を「現在、標準出力 (1) に割り当てられている出力先」に切り替える
2>&1 … 標準エラー出力 (2) の出力先を「現在、標準エラー出力 (2) に割り当てられている出力先」に切り替える

となり、リダイレクト処理実行時点の出力先が使われるという意味にちゃんと読み取れます。
まあ、これはこのブログ記事の作者が考えた文章だと思うので、これを根拠にするのはおかしいですが、記事が間違っているわけではないと言うことです。

強いて言えば、「1コマンドに複数のリダイレクト指定があった場合には、前から順番に一つずつ処理される」という説明があればよい気ももしますが、自明と思って書かなかったのでしょうね。

man bashだと以下の記述です。

リダイレクトの順番には意味がある点に注意してください。 例えば、次のコマンド
ls > dirlist 2>&1
は標準出力と標準エラー出力を両方ともファイル dirlist に書き込みますが、次のコマンド
ls 2>&1 > dirlist
では標準出力だけがファイル dirlist に書き込まれます。なぜなら後者の場合には、標準エラー出力は dirlist にリダイレクトされる前の標準出力の複製となるからです。

Bashのことで分からないことがある場合は、man bashを見るのが一番です。

投稿2023/10/12 08:56

編集2023/10/12 08:57
otn

総合スコア86324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hokuyan

2023/10/13 09:40

詳細なご回答ありがとうございます。 確かに言葉を代入するとわかりやすいですね。
guest

0

ベストアンサー

ファイルディスクリプタは変数になっていて、それぞれに入出力先が「代入」されている、と考えるのがわかりやすいです。

リダイレクトは、今の設定状況をコピーするだけで、後からさらにリダイレクトを行っても影響を及ぼしません。

  • (最初)… 1:標準出力、2:標準エラー出力
  • 1>&2…1:標準エラー出力、2:標準エラー出力
  • >&2 2> ./sample_out.txt…1:標準エラー出力のまま、2:./sample_out.txt

投稿2023/10/12 08:28

maisumakun

総合スコア146628

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hokuyan

2023/10/13 09:36

ご回答ありがとうございます! ディスクリプタを変数と考える考え方がしっくりきました。 ファイルディスクリプタという変数に、標準出力・標準エラー出力・ファイル出力といういずれかの値を代入する感じですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問