为什么我无法检索从反引号内部暂停的程序?

时间:2019-09-16 18:00:16

标签: c tty ctrl termcap

我创建了一个程序,该程序使用参数列表并将其放在新tty的网格中,我可以在其中移动并从中选择所需的内容。

当我运行程序时没有这样的反引号...

$> ./ft_select arg_1 arg_2 ... arg_N

打开一个新的tty并显示一个网格...

arg_1  arg_2  arg_3
arg_4  arg_5  arg_6
arg_7  ...    arg_N

我击中ctrl+z,程序毫无问题地被挂起,fg命令将其放回原处。

我的问题是,当我将命令放在反引号之间并尝试将其挂起时,它卡住了而没有给出提示。

我不得不提到,我将网格的所有内容写在/dev/tty

您可以在下面的代码中找到执行信号处理的功能。

 23 void    signalhandler(int sig)
 24 {
 25 //  struct winsize  ws;
 26
 27     if (sig == SIGWINCH)
 28     {
 29 //      ioctl(g_data->tty, TIOCGWINSZ, &ws);
 30         update_data(g_data);
 31         print_args(g_data);
 32         update_cursor(g_data, 1);
 33     }
 34     else if (sig == SIGTSTP)
 35     {
 36         signal(SIGTSTP, SIG_DFL);
 37         enable_cap("te");
 38         modify_main_caps(SET, g_data->tty);
 39         ioctl(g_data->tty, TIOCSTI, "\032");
 40     }
 41     else if (sig == SIGCONT)
 42     {
 43         signal(SIGTSTP, signalhandler);
 44         modify_main_caps(UNSET, g_data->tty);
 45         update_data(g_data);
 46         print_args(g_data);
 47         update_cursor(g_data, 1);
 48     }
 49     else if (sig == SIGINT)
 50     {
 51         enable_cap("te");
 52         modify_main_caps(SET, g_data->tty);
 53         exit(EXIT_FAILURE);
 54     }
 55 }

2 个答案:

答案 0 :(得分:1)

CTRL + Z 使终端设备驱动程序将SIGTSTP发送到前台进程组中的所有进程。至少在bashzsh中,命令替换$(<command>)中的命令在子shell中执行,但是它们没有得到自己的进程组(它们与父外壳本身在同一进程组中运行)。这意味着 CTRL + Z 完全不会影响它们-按下它并没有任何反应,就像按下 CTRL + Z < / kbd>在shell提示符下什么也不做:在两种情况下,都没有要挂起的前台进程组!

答案 1 :(得分:0)

我认为您正在寻找this question中讨论的问题的另一种形式。

将命令放在反引号中不仅仅是运行它的另一种方式;它告诉外壳程序在子外壳程序中运行该命令并替换结果。这称为command substitution,也可以表示为$(command)(此语法更现代,usually preferred)。

命令替代的主要用途是,它使您可以将一个命令的输出用作另一个命令的输入。例如,查看以下命令的结果:

echo "1 + 1 = $(expr 1 + 1)" # prints "1 + 1 = 2"
echo "2 + 2 = `expr 2 + 2`"  # prints "2 + 2 = 4"
echo "1 + (4 / 2) = $(expr 1 + $(expr 4 / 2))" # prints "1 + (4 / 2) = 3"

当您使用命令替换代替命令本身时,扩展仍然有效,尝试运行命令并将其输出包含在shell的输入中。因此,当您以替代方式运行命令时,它将尝试运行命令,并接受所有输入,然后尝试运行结果显示的内容。

我不确定当您尝试暂停这些操作时会发生什么,但是我的测试给出了一些异常行为:尝试暂停$(cat)并没有执行任何操作,但是暂停$(rlwrap cat)时崩溃了,并离开了终端我杀死它后感到困惑。但是我知道子shell不会与实际的shell作业一起管理,因此您将无法管理在子shell中运行的命令。