2012-09-22 17 views
5

के लिए बाहर निकलने से पहले कई बार fgets loops मैं एक साधारण खोल बना रहा हूँ। इसे लाइनों द्वारा पाठ फ़ाइलों को पढ़ने में भी सक्षम होना चाहिए। यह मेरा कोड है:ईओएफ

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <sys/stat.h> 

// Exit when called, with messages 
void my_exit() { 
    printf("Bye!\n"); 
    exit(0); 
} 

int main(void) { 

    setvbuf(stdout, NULL, _IONBF, 0); 

    // Char array to store the input 
    char buff[1024]; 

    // For the fork 
    int fid; 

    // Get all the environment variables 
    char dir[50]; 
    getcwd(dir,50); 
    char *user = getenv("USER"); 
    char *host = getenv("HOST"); 

    // Issue the prompt here. 
    printf("%[email protected]%s:%s> ", user, host, dir); 

    // If not EOF, then do stuff! 
    while (fgets(buff, 1024, stdin) != NULL) { 

    // Get rid of the new line character at the end 
    // We will need more of these for special slash cases 
    int i = strlen(buff) - 1; 
    if (buff[i] == '\n') { 
     buff[i] = 0; 
    } 

    // If the text says 'exit', then exit 
    if (!strcmp(buff,"exit")) { 
     my_exit(); 
    } 

    // Start forking! 
    fid = fork(); 

    // If fid == 0, then we have the child! 
    if (fid == 0) { 

     // To keep track of the number of arguments in the buff 
     int nargs = 0; 

     // This is a messy function we'll have to change. For now, 
     // it just counts the number of spaces in the buff and adds 
     // one. So (ls -a -l) = 3. AKA 2 spaces + 1. Really in the 
     // end, we should be counting the number of chunks in between 
     // the spaces. 
     for (int i = 0; buff[i] != '\0'; i++) { 
     if (buff[i] == ' ') nargs ++; 
     } 

     // Allocate the space for an array of pointers to args the 
     // size of the number of args, plus one for the NULL pointer. 
     char **args = malloc((sizeof(char*)*(nargs + 2))); 

     // Set the last element to NULL 
     args[nargs+1] = NULL; 

     // Split string into tokens by space 
     char *temp = strtok (buff," "); 

     // Copy each token into the array of args 
     for (int i = 0; temp != NULL; i++) { 
     args[i] = malloc (strlen(temp) + 1); 
     strcpy(args[i], temp); 
     temp = strtok (NULL, " "); 
     } 

     // Run the arguments with execvp 
     if (execvp(args[0], args)) { 
     my_exit(); 
     } 
    } 

    // If fid !=0 then we still have the parent... Need to 
    // add specific errors. 
    else { 
     wait(NULL); 
    } 

    // Issue the prompt again. 
    printf("%[email protected]%s:%s> ", user, host, dir); 
    } 

    // If fgets == NULL, then exit! 
    my_exit(); 
    return 0; 
} 

जब मैं इसे खोल के रूप में अकेले चलाता हूं, तो यह बहुत अच्छा काम करता है। जब मैं चलाता हूं ./myshell < command.txt, यह काम नहीं करता है।

commands.txt है:

ls -l -a 
pwd 
ls 

लेकिन उत्पादन होता है:

>Bye! 
>Bye! 
>Bye! 
>Bye! 
>Bye! 
>Bye!>Bye! 
>Bye! 
>Bye! 
>Bye! 

भी मेरी आदेशों को चलाने के नहीं है। कोई विचार? मैंने सोचा कि मेरा लूप बहुत आसान था।

+0

प्रयास करें और कौन क्या मुद्रण को देखने के लिए my_exit() में प्रक्रिया का पीआईडी ​​मुद्रित करें। –

+0

आपको प्रॉम्प्ट प्रिंट करने के बाद कम से कम आउटपुट फ्लश करने की आवश्यकता है ताकि यह कमांड आउटपुट के सापेक्ष सही जगह पर आ जाए। –

+0

पीआईडी ​​को प्रिंट करना, मुझे पिछले 0 को छोड़कर सभी 0 (प्रत्येक अलविदा के लिए!) मिलते हैं, जो 1 9 147 – user1687558

उत्तर

3

अगर यह है समस्या मैं नहीं जानता, लेकिन आप (सही) एक टिप्पणी आप आवंटित करने के लिए है "प्लस शून्य सूचक के लिए एक" *args सरणी में है कि में उल्लेख है।

हालांकि, आप वास्तव में अंतिम सूचक को *args में NULL में सेट नहीं करते हैं।

execvp() इसे पसंद नहीं करेंगे।

यह स्पष्ट नहीं करता है कि पुनर्निर्मित बनाम गैर-पुनर्निर्देशित इनपुट के बीच कोई अंतर क्यों हो सकता है, अपरिभाषित व्यवहार के अलावा, एक बेस्टर्ड है।

+0

धन्यवाद - मैंने अंतिम पॉइंटर को न्यूल पर सेट किया है और अजीब व्यवहार अभी भी – user1687558

1

क्षमा करें सबको - मेरी टेक्स्ट फ़ाइल मैक के टेक्स्ट एडिट GUI से किसी प्रकार के डिमेंटेड प्रारूप में बदल गई है। सब कुछ अच्छा काम कर रहा है।

मैं वास्तव में मददगार की सभी प्रतिक्रियाओं की सराहना करते हैं

+0

हो रहा है क्या आप प्रारूप के बारे में क्या सोच रहे थे, और कैसे डिमेंशिया स्वयं प्रकट हुआ? –

+0

ज़रूर! मैंने TextEdit फ़ाइल को सेव किया है, लेकिन यह .rtf था - इसलिए मैंने इसका नाम बदलकर .txt कर दिया ... इसके परिणामस्वरूप फ़ाइल के शीर्ष पर (आरटीएफ प्रारूप के बारे में) अजीब अक्षर सामने आए। तो जब प्रोग्राम .txt इनपुट के साथ चला गया, तो यह पूरी तरह से अजीब आदेश निष्पादित करने का प्रयास कर रहा था। मैंने cat command.txt को आजमाकर पाया ... कारण मैं टेक्स्ट एडिट का उपयोग पहली जगह में कर रहा था क्योंकि मैं अपने मैक @ होम के माध्यम से अपने यूनिक्स सर्वर में एसएसएचिंग कर रहा हूं। मैं परीक्षण के लिए एक टेक्स्ट फ़ाइल बनाना चाहता था, इसलिए मैंने इसे टेक्स्ट एडिट में बनाया और साइबरडक को एससीपी में इस्तेमाल किया। – user1687558

संबंधित मुद्दे