0

我创建了一个程序,它接受一个参数列表并将它们放在一个新 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 }
4

2 回答 2

1

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

于 2019-09-16T21:14:36.920 回答
0

I think you're looking at a variation of the issue discussed in this question.

Putting a command in backquotes isn't just another way to run it; it tells the shell to run that command in a subshell and substitute the results. This is called command substitution, and can also be represented as $(command) (this syntax is more modern and usually preferred).

The main use of command susbtitution is that it lets you use the output of one command as the input to another. For example, look at the results of these commands:

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"

When you use command substitution in place of the command itself, the the expansion still works, attempting to run the command and include its output in the shell's input. So when you run your command in a substitution, it tries to run your command, taking all of its input, then should try to run whatever it prints as the result.

I'm not exactly sure what happens when you try to suspend these, but my testing gave some unusual behaviors: trying to suspending $(cat) did nothing, but suspending $(rlwrap cat) crashed, and left the terminal confused after I killed it. But I do know that subshells aren't managed along with actual shell jobs, so you won't be able to manage a command that you run in a subshell.

于 2019-09-16T18:54:15.677 回答