Why can't I retrieve my program that was suspended from inside backticks?

三世轮回 提交于 2020-03-05 04:28:07

问题


I created a program that takes a list of arguments and put them in a grid on a new tty where I can move around and select from it what I want.

When I run the program without backticks like this...

$> ./ft_select arg_1 arg_2 ... arg_N

A new tty is opened and a grid is shown...

arg_1  arg_2  arg_3
arg_4  arg_5  arg_6
arg_7  ...    arg_N

I hit ctrl+z and the program gets suspended with no problem and fg command puts it back.

My problem is that when I put the command between backticks and I try to suspend it, it get stuck without giving the prompt back.

I have to mention that I write all the content of the grid on /dev/tty

You can find in the code below the function that does the signal handling.

 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 }

回答1:


CTRL+Z causes the terminal device driver to send a SIGTSTP to all processes in the foreground process group. In bash and zsh, at least, commands in a command substitution $(<command>) are executed in a subshell, but they don't get their own process group (they run in the same process group as the parent shell itself). That means that CTRL+Z should not affect them at all - press it and nothing happens, just like pressing CTRL+Z in a shell prompt doesn't do anything: in both cases, there is no foreground process group to suspend!




回答2:


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.



来源:https://stackoverflow.com/questions/57962161/why-cant-i-retrieve-my-program-that-was-suspended-from-inside-backticks

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!