gpt4 book ai didi

c - 启动 shell 时如何撤消 freopen 的影响?

转载 作者:太空宇宙 更新时间:2023-11-04 03:46:45 25 4
gpt4 key购买 nike

一段代码使用 freopen 将标准输出与 C 中的文件联系起来。在这段代码之后,将执行一个启动 shell 的脚本。现在的问题是所有 stdout 输出都进入该文件,因此在该 shell 中运行的任何命令都被放置在该文件中。

我已经找到启动 shell 的脚本:

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

虽然它打印到屏幕上,但我不确定如何验证它实际上是打印到 stdout 还是 stderr。有人可以验证我的 IO 重定向是否正确吗?

编辑:我无权访问调用 freopen 的程序,只能访问要运行的脚本。

最佳答案

你的 shell 片段:

  • 使标准输出(1)转到标准错误(2)当前所在的位置;和
  • 使标准错误 (2) 转到标准输出 (1) 当前所在的位置。

不需要第二次操作

原始答案

更严重的是,如果代码段被调用时其标准错误将转到一个文件,那么 shell 的输出将转到同一个文件。如果您确实希望它与原始标准输出到达同一位置,则需要在使用 freopen() 重定向之前保留原始标准输出。你会这样做:

int fd1 = dup(FILENO_STDOUT);

...now do freopen...


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

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

修改后的答案

给定场景:

  • 登录 shell 用于运行程序 Program-A(您没有源代码,它在标准输出上使用 freopen())
  • 程序 A 运行程序 B(这是一个 shell 脚本,最终启动交互式 shell,使用 /bin/sh 1>&2 2>&1 符号)

并且假设您希望交互式 shell 的标准输出转到原始标准输出,那么您可以使用以下代码执行此操作:

启动.sh

运行程序 A 并设置额外的 I/O 重定向和环境变量:

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

模拟不可修改程序的 Shell 脚本。它在将标准输出更改为文件 (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 选项调用交互式 shell。 2>&1 将标准错误重定向到标准输出所在的位置。交互式 shell 提示标准错误(因为我再次以艰难的方式发现 - 尽管我以前遇到过这种行为)。

示例运行

isodate 命令等同于 date +'%Y-%m-%d %H:%M:%S'。我在机器 osiris 上的标准提示符是 Osiris 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:

关于c - 启动 shell 时如何撤消 freopen 的影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23770975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com