簡體   English   中英

命令后如何保持我的外殼運行

[英]How to keep my shell running after a command

我在另一個Shell中運行此基本Shell程序。 我無法弄清楚為什么執行“ ls”后我的shell無法繼續運行。 我沒有出口,但可以回到原始外殼。 如果要使用它,我必須每次都運行我的shell程序。 我想這就是fork()應該做什么。 我只希望我的shell使用我用if else語句編碼的exit命令退出。 任何建議將不勝感激。 哦,不要理會gettoks()解析器函數,我無法弄清楚如何使用它進行輸入,因此我為字符串輸入cmSTR編寫了if else語句,而不是使用gettoks()解析器。 主要是因為我不知道如何將輸入傳遞給它

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include <cstdlib>
#include <sys/wait.h>

using namespace std;
// Initializing counters for trapping
static int cc_counter = 0;
static int cz_counter = 0;
static int cq_counter = 0;
//Functions for trap signal handler
void cc_handler( int signo )
{
++cc_counter;
}
void cz_handler( int signo )
{
++cz_counter;
}
void cq_handler( int signo )
{
++cq_counter;
}

//*********************************************************
//
// Extern Declarations
//
//*********************************************************
using namespace std;
extern "C"
{
extern char **gettoks();
} 


//*********************************************************
//
// Main Function
//
//*********************************************************
int main( int argc, char *argv[] )
{
// local variables
int ii;
char **toks;
int retval;

// initialize local variables
ii = 0;
toks = NULL;
retval = 0;
char buf[1000];//Initialize of size for current working directory
string cmSTR;//String to hold input
int status;//Initialization of status for fork()
pid_t pid;//Declaration of pid

// main (infinite) loop
while( true )
{
    signal( SIGINT, cc_handler );// Traps Ctrl+C
    signal( SIGTSTP, cz_handler);// Traps Ctrl+Z
    signal( SIGQUIT, cq_handler);// Traps Ctrl+\
  //prompt and show current working directory
  cout <<("RS_SHELL:") << getcwd(buf,1000) << "\t";
  getline(cin ,cmSTR);//read input from keyboard
  // if else loop to switch based on command input
  if(cmSTR == "ls")// if ls, then execute arguement
  {
    execl( "/bin/ls", "ls", NULL );//System call to execute ls

    }
    else if(cmSTR == "exit")//if exit, then execute block of code
    {
        cout << "Ctrl C entered: " << ++cc_counter << "times"<< endl;
        cout << "Ctrl Z entered: " << ++cz_counter << "times"<< endl;
        cout << "Ctrl Back Slash entered: " << ++cq_counter << "times"<< endl;
        exit(1);
        }
    else if(cmSTR == "guish")// if guish, execute guish shell
    {
        execvp("guish", NULL);
        }
        //if input is not any of previous commands then fork()
    else if(cmSTR != "ls" && cmSTR != "exit" && cmSTR != "guish" && cmSTR != "\n")
    {
        pid = fork();
        if (pid < 0)//Loop to fork parent and child process
        {
            fprintf(stderr, "Fork Failed");
            exit(-1);
            }
            else if (pid == 0)//Child process
        {
            execvp("guish", NULL);//system call to execute guish shell

            }
            else //Parent process
            {
                waitpid( -1, &status,0);
                exit(0);
                }
                }




  // get arguments
  toks = gettoks();

  if( toks[0] != NULL )
{
  // simple loop to echo all arguments
  for( ii=0; toks[ii] != NULL; ii++ )
    {
      cout << "Argument " << ii << ": " << toks[ii] << endl;
    }

  if( !strcmp( toks[0], "exit" ))
    break;
 }
    }

   // return to calling environment
   return( retval );
   }

如您所懷疑, execl及其相關功能將當前過程與新過程重疊。 因此,在啟動lsexecl調用之后,您的程序將不再存在以保持運行。

如果要讓shell程序在運行ls之后繼續存在,則需要在調用execl( "/bin/ls", "ls", NULL ); 之前添加fork() execl( "/bin/ls", "ls", NULL );

同樣,如果您希望ls的輸出與shell出現在同一控制台中,正如我想的那樣,您將需要將ls的輸出通過管道傳回到shell,然后將其輸出到shell的控制台中。 請參閱編寫我自己的外殼……卡在管道上? , 例如。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM