0

I have created a mini shell in C that operates like a bash. Like bash, my mini shell supports working history. I use arrow keys to go up and down over commands executed previously. When I execute a command with multiple pipes which takes some time to execute and use arrow keys to go up and down before the execution is done it results in a problem. For example, imagine I executed some commands (to fill the history) and then used multiple pipes and executed sleep 10 in each of them...

minishell> ls
file.txt
minishell> pwd
/
minishell>cd -
minishell>

Now history file contains commands cd -, pwd, ls. When I use arrow keys I normally get that commands on the terminal. Now when I execute this part after that...

minishell> sleep 10 | sleep 10 | sleep 10

This sleeps 30 seconds and during that, I use arrow keys to go up ad down. The cursor goes up and down but nothing is displayed until 30 seconds pass. After 30 seconds I get the prompt back but when I go up and dow to list the commands in history I get something like this...

minishell> sleep 10 | sleecd-

then I do another up arrow and it becomes

minishell> sleep 10 | sleepwd

then another one

minishell> sleep 10 | sleels

It just takes the part of the last command with sleep (sleep 10 | slee) and appends previously used commands to it. I do not understand why I get this behavior. The expected behavior is that after sleeps it should give me commands cd - then pwd then ls but not appended as shown above.

I use add_history from history.h to keep the input line in the history file. You can observe my main function.

#include "../includes/minishell.h"
t_mini g_mini;

int main(int argc, char **argv, char **env)
{
        char    *line;

        (void) argc;
        (void) argv;
        init(&g_mini, env);
        sig_init();
        while (1)
        {
                line = readline("\033[0;36m\033[1mminishell ▸ \033[0m");
                if (!line)
                {
                        ft_putstr_fd("minishell: exit \n", STDERR);
                        return (SUCCESS);
                }
                parse_and_execute(line);
                if (ft_strcmp(line, ""))
                        add_history(line);
                free(line);
        }
        return (SUCCESS);
}

Also, I wanna note that I use a fork to execute each command, except in the case when I have many commands. In a word when I have multiple pipes I create a process for each command, execute them there and wait for them in the main.

I would be glad if someone could help me understand why I get this weird behavior while using arrow keys after multiple pipe commands.

You can find my full mini shell code here https://github.com/42YerevanProjects/42_minishell.git

  • Sounds like when you go up multiple times, you're not clearing the line before displaying the next line in history. – Barmar Jan 07 '22 at 19:59
  • 1
    `sleep 10 | sleep 10 | sleep 10` should only sleep for 10 seconds. All the processes in a pipeline should run at the same time, not sequentially. – Barmar Jan 07 '22 at 20:00
  • You need to post your history code that shows how you redisplay the command line when you navigate in history. – Barmar Jan 07 '22 at 20:02
  • @Barmar the only place I use history is the line add_history(line) in main. Should I do anything else except adding to history in order to et normal listing while using arrow keys. – Sargis Hovsepyan Jan 07 '22 at 20:31
  • The problem is due to the escape sequences in the prompt. See the linked question for the solution. – Barmar Jan 07 '22 at 20:42
  • @Barmar Thank you very much it actually helped – Sargis Hovsepyan Jan 07 '22 at 21:49

0 Answers0