1

コードの一部は、freopen を使用して C のファイルに stdout を関連付けます。このコードの後に​​、シェルを起動するスクリプトが実行されます。問題は、すべての stdout 出力がそのファイルに送られるため、そのシェルで実行されるすべてのコマンドがそのファイルに配置されることです。

シェルを起動するこのスクリプトにたどり着きました:

/bin/sh 1>&2 2>&1

画面に出力されますが、実際に stdout と stderr に出力されていることを確認する方法がわかりません。IOリダイレクトが正しく行われたことを誰かが確認できますか?

編集: freopen を呼び出すプログラムにはアクセスできません。実行するスクリプトだけです。

4

1 に答える 1

1

あなたのシェルフラグメント:

  • 標準出力 ( ) を、標準エラー ( ) が現在出力1されている場所に出力します。2
  • 標準出力 ( ) が現在2出力されている場所に、標準エラー ( ) が出力されるようにします。1

2 回目の操作は必要ありません。

元の答え

さらに深刻なことに、標準エラーがファイルに出力される状態でコードが呼び出された場合、シェルの出力は同じファイルに出力されます。本当に元の標準出力と同じ場所に出力したい場合は、 でリダイレクトする前に元の標準出力を保持する必要がありますfreopen()。次のようにします。

int fd1 = dup(FILENO_STDOUT);

...now do freopen...


dup2(fd1, FILENO_STDOUT);
close(fd1);

...now launch shell...without I/O redirection

修正された回答

シナリオを考えると:

  • ログインシェルは、プログラム Program-A を実行するために使用されます (ソースがなく、freopen()標準出力を使用します)。
  • /bin/sh 1>&2 2>&1Program-A は Program-B を実行します (これは、表記法を使用して対話型シェルを起動するシェル スクリプトです)。

また、インタラクティブ シェルの標準出力を元の標準出力に出力したい場合は、次のコードを使用してこれを行うことができます。

launch.sh

追加の I/O リダイレクトと環境変数を設定して Program-A を実行します。

set -x
fd -n 32
exec 3>&1
echo "$0: $@"
fd -n 32
FD_COPY_STDIN=3 exec ./Program-A "$@"

fdプログラムは、開いているファイル記述子と閉じているファイル記述子を出力しoます-。は、-n 32「最初の 32 個のファイル記述子のステータスを出力」を指定します (デフォルトでは、考えられるすべてのファイル記述子を出力しますが、64 個のダッシュで構成される数百行は読むのが非常に退屈です)。

プログラム-A

変更不可能なプログラムをシミュレートするシェル スクリプト。標準出力をファイル ( standard.output) に移動するように変更した後、Program-B を実行します。

set -x
echo "$0: $@"
# Simulate freopen("./standard.output", "w", stdout);
exec 1> ./standard.output
echo "$0: $@"
fd -n 32
exec ./Program-B "$@"

(必要に応じて、最後のものを削除して、終了exec後に何かをエコーすることもできProgram-Bます。)

プログラム-B

これは修正したスクリプトです — によって実行されるプログラムProgram-A:

echo "$0: $@"
fd -n 32

exec 1>&${FD_COPY_STDOUT:-3}
exec 3>&- 2>&1
echo "$0: $@"
fd -n 32
exec ${SHELL} -i

(繰り返しますが、最終的なexecものを削除して、後でスクリプト内で別のことを行うことができます。)

この-iオプションは、対話型シェルを呼び出します。2>&1標準エラーを、標準出力と同じ場所にリダイレクトします。インタラクティブ シェルは、標準エラーでプロンプトを表示します (これも難しい方法であることがわかりましたが、以前にこの動作に遭遇したことがあります)。

実行例

コマンドはisodateと同等date +'%Y-%m-%d %H:%M:%S'です。マシン上の私の標準プロンプトosirisOsiris JL:.

ファイルにリダイレクトされる標準エラーなし:

Osiris JL: ls
launch.sh  Program-A  Program-B
Osiris JL: bash launch.sh $(isodate)
+ fd -n 32
ooo-----------------------------
+ exec
+ echo 'launch.sh: 2014-05-20' 17:03:59
launch.sh: 2014-05-20 17:03:59
+ fd -n 32
oooo----------------------------
+ FD_COPY_STDIN=3
+ exec ./Program-A 2014-05-20 17:03:59
+ echo '/home/jleffler/soq/New/Program-A: 2014-05-20' 17:03:59
/home/jleffler/soq/New/Program-A: 2014-05-20 17:03:59
+ exec
+ echo '/home/jleffler/soq/New/Program-A: 2014-05-20' 17:03:59
+ fd -n 32
+ exec ./Program-B 2014-05-20 17:03:59
/home/jleffler/soq/New/Program-B: 2014-05-20 17:03:59
ooo-----------------------------
jleffler@osiris:~/soq/New$ ls -l
total 16
-rwxr----- 1 jleffler eng 100 May 20 17:02 launch.sh
-rwxr----- 1 jleffler eng 158 May 20 17:02 Program-A
-rwxr----- 1 jleffler eng 121 May 20 17:02 Program-B
-rw-r----- 1 jleffler eng 208 May 20 17:03 standard.output
jleffler@osiris:~/soq/New$ exit
exit
Osiris JL:

標準エラーがファイルにリダイレクトされる場合:

Osiris JL: bash launch.sh $(isodate) 2>standard.error
ooo-----------------------------
launch.sh: 2014-05-20 17:05:11
oooo----------------------------
/home/jleffler/soq/New/Program-A: 2014-05-20 17:05:11
/home/jleffler/soq/New/Program-B: 2014-05-20 17:05:11
ooo-----------------------------
jleffler@osiris:~/soq/New$ ls -l
total 20
-rwxr----- 1 jleffler eng 100 May 20 17:02 launch.sh
-rwxr----- 1 jleffler eng 158 May 20 17:02 Program-A
-rwxr----- 1 jleffler eng 121 May 20 17:02 Program-B
-rw-r----- 1 jleffler eng 343 May 20 17:05 standard.error
-rw-r----- 1 jleffler eng 208 May 20 17:05 standard.output
jleffler@osiris:~/soq/New$ exit
exit
Osiris JL: cat standard.error
+ fd -n 32
+ exec
+ echo 'launch.sh: 2014-05-20' 17:05:11
+ fd -n 32
+ FD_COPY_STDIN=3
+ exec ./Program-A 2014-05-20 17:05:11
+ echo '/home/jleffler/soq/New/Program-A: 2014-05-20' 17:05:11
+ exec
+ echo '/home/jleffler/soq/New/Program-A: 2014-05-20' 17:05:11
+ fd -n 32
+ exec ./Program-B 2014-05-20 17:05:11
Osiris JL: cat standard.output
/home/jleffler/soq/New/Program-A: 2014-05-20 17:05:11
oooo----------------------------
/home/jleffler/soq/New/Program-B: 2014-05-20 17:05:11
oooo----------------------------
Osiris JL: 
于 2014-05-20T22:57:21.203 に答える