2016-06-11 2 views
0

私は、カスタムシェルを書いていると私はそれがスクリプトを実行したい:私はbashのから、私のカスタムシェルで実行すると、それが動作カスタムシェル用のシーブン?

if [ type less > /dev/null ];then PAGER=less; fi 
echo $PAGER 
printenv|grep $1|$PAGER 

$ ./shell -f ../checkenv.sh GNOME 
[13607] 
[13606] 
GNOME_KEYRING_CONTROL= 
GNOME_KEYRING_PID= 
GNOME_DESKTOP_SESSION_ID=this-is-deprecated 
INSTANCE=GNOME 
XDG_CURRENT_DESKTOP=GNOME 
(END) 

でもあれば、私私のシェルを起動し、スクリプトを実行しようとすると、エラーメッセージが表示されます。

$ ./shell 
'PATH' is set to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin. 
$ ../checkenv.sh GNOME 
14786: executing ../checkenv.sh 
../checkenv.sh: 2: [: type: unexpected operator 

14786: executed 
$ 

これは私がシェバングを持っていないためと考えられるが、私は、カスタムシェルのシェバングを使用する方法がわかりません。 /usr/bin/に私のカスタムシェルをインストールすべきか、それとも別の手配をするべきですか?

私の主な機能と私のreadlineの機能は次のとおりです。

int main(int argc, char *argv[]) { 
    bool donotrun = false; 
    struct sigaction new_action, old_action; 
    hashtable_t *hashtable = ht_create(65536); 
    /* Set up the structure to specify the new action. */ 
    new_action.sa_handler = termination_handler; 
    sigemptyset(&new_action.sa_mask); 
    new_action.sa_flags = 0; 

    sigaction(SIGINT, NULL, &old_action); 
    if (old_action.sa_handler != SIG_IGN) 
     sigaction(SIGINT, &new_action, NULL); 
    sigaction(SIGHUP, NULL, &old_action); 
    if (old_action.sa_handler != SIG_IGN) 
     sigaction(SIGHUP, &new_action, NULL); 
    sigaction(SIGTERM, NULL, &old_action); 
    if (old_action.sa_handler != SIG_IGN) 
     sigaction(SIGTERM, &new_action, NULL); 

    bool background = false; 
    int index = 0; 
    int i; 
    char *cvalue = NULL; 
    const char *commandFile = NULL; 

    while (1) { 
     index = 0; 
     i = getopt_long(argc, argv, "pc:fvh", 
         options, &index); 
     if (i == -1) 
      break; 
     switch (i) { 
      case 'p': { 
       exit(EXIT_SUCCESS); 
      } 
      case 'v': { 
       printf("sh OpenShell version 0.1(a)\n"); 
       printf("Version: %s\n", VERSION); 

       // printf ("%s/%s/%s/%s\n", 
       //   program_name, version, 
        //  build_date, build_git_sha); 


       exit(EXIT_SUCCESS); 

      } 
      case 'h': { 
       usage(); 
       exit(EXIT_SUCCESS); 

      } 
      case 'c': { 
       cvalue = optarg; 
       command(cvalue, hashtable, background); 
       exit(EXIT_SUCCESS); 
      } 

      case 'f': { 
       /* 
       * Execute commands from file. 
       * This is used for osh script files. 
       * The quiet flag is also set. 
       */ 
       //if ((argc != 1) || commandFile) 
        //usage(); 
       //quietFlag = TRUE; 
       printf("case f\n"); 
       //commandFile = *argv++; 

       argc--; 
       *argv++; 
       *argv++; 
       readFile(*argv++, argc, argv, hashtable, background); 
       //free(line); 
       exit(0); 

       //break; 
      } 

      case '?': 
       if (optopt == 'c') 
        fprintf(stderr, "Option -%c requires an argument.\n", optopt); 
       else if (isprint (optopt)) 
        fprintf(stderr, "Unknown option `-%c'.\n", optopt); 
       else 
        fprintf(stderr, 
          "Unknown option character `\\x%x'.\n", 
          optopt); 
      default: { 
       return 1; 
      } 
     } 
    } 
    getPath(); 
    char *copy = ""; 

    for (; ;) { 
     bool scanning = true; 
     while (scanning) { 
      char *line = NULL; 
      line = readline("$ "); 
      if (line == NULL) { 
       /* No more lines, so exit the loop. */ 
       break; 
      } 
      if (line) 
       copy = strdup(line); 

      if (line && !strstr(line, "for") && !strstr(line, "==") && !strstr(line, "if") && strstr(line, "=")) { 
       donotrun = true; 
       char str[128]; 
       char *ptr; 
       strcpy(str, line); 
       strtok_r (str, "=", &ptr); 
       ht_set(hashtable, str, ptr); 
      } 

      if (!scanning) 
       break; 

      if (commandFile!=NULL || !isatty(fileno(stdin))) { 
       *argv++; 
       readFile(*argv++, argc, argv, hashtable, background); 
       free(line); 
       exit(0); 
      } 
      else { 
       if (!donotrun) { 
        line = strrep(line, " | ", "|"); 
        line = strrep(line, " |", "|"); 
        background = testFn2(line); 
        if (background) 
         line[strlen(line) - 1] = '\0'; 
        command(line, hashtable, background); 
       } 
       donotrun = false; 
       add_history(copy); 

      } 
      free(copy); 
     } 
    } 
    // ParseFree(pParser, free);FIXME: where should this go? 
    return 0; 
} 


/* 
* Read commands from the specified file. 
* A null name pointer indicates to read from stdin. 
*/ 
static int readFile(const char *name, int argc, char ** argv, hashtable_t *hashtable, bool background) { 
    FILE *fp; 
    int cc; 
    bool ttyFlag; 
    char buf[CMD_LEN]; 
    int r = 0; 

    if (sourceCount >= MAX_SOURCE) { 
     fprintf(stderr, "Too many source files\n"); 

     return 1; 
    } 

    fp = stdin; 
    printf("name %s\n", name); 

    if (name) { 
     fp = fopen(name, "r"); 

     if (fp == NULL) { 
      perror(name); 

      return 1; 
     } 
    } 

    sourcefiles[sourceCount++] = fp; 

    ttyFlag = isatty(fileno(fp)); 
    int i = 0; 
    while (true) { 
     if (ttyFlag) 
      showPrompt(); 

     if (intFlag && !ttyFlag && (fp != stdin)) { 
      fclose(fp); 
      sourceCount--; 

      return 1; 
     } 
     if (fgets(buf, CMD_LEN - 1, fp) == NULL) { 
      if (ferror(fp) && (errno == EINTR)) { 
       clearerr(fp); 

       continue; 
      } 

      break; 
     } 

     cc = strlen(buf); 
     if (buf[cc - 1] == '\n') 
      cc--; 

     while ((cc > 0) && isBlank(buf[cc - 1])) 
      cc--; 

     buf[cc] = '\0'; 
     //printf("buf %s\n", argv[0]); 
     strreplace(buf, "$1", argv[0]); 

     //printf("arg %s\n", ++argv); 

     if (strstr(buf, "=")) { 
      char str[128]; 
      char *ptr; 
      strcpy(str, buf); 
      strtok_r (str, "=", &ptr); 
      ht_set(hashtable, str, ptr); 
     } 

     //printf("the command is %s\n", buf); 
     r = command(buf, hashtable, background); 
     i++; 
    } 

    if (ferror(fp)) { 
     perror("Reading command line"); 

     if (fp == stdin) 
      exit(1); 
    } 

    clearerr(fp); 

    if (fp != stdin) 
     fclose(fp); 

    sourceCount--; 

    return r; 
} 
+1

これがCやシェルのソースコードとどのように関係しているかは不明です。 She-bangは実行環境の特徴であり、Cに関連する方法はありません。 – Olaf

+3

'#!/ path/to/my/shell'を試してみてどうしたらいいでしょうか? – a3f

+0

ところで、 '[]'は 'if'構文の一部ではありません。これは、グループ化演算子と同じまたは代替の括弧または中括弧ではありません。文字通り、 '['は 'test'コマンドのエイリアスです。 if [2-gt 1] 'は**あらゆる点で** ** if test 2 -gt 1'と同じです(私が読んだソースは同じ関数で実装されています)あなたのOSは/ usr/bin/['/ usr/bin/test'と同じように' '/ usr/bin/[' 'を提供します(現代のシェルには、 )。 –

答えて

1

あなたは単にあなたのスクリプトのテストに角括弧を削除する場合があります

if type less > /dev/null ;then PAGER=less; fi 
echo $PAGER 
printenv|grep $1|$PAGER 
2

シェバング行は単にインタプリタへのフルパスを指定します、プラス(必要に応じて)渡される引数。

カスタムシェルには-fが必要で、その後にスクリプト名が続き、その後にスクリプトに渡す引数が必要です。

だからあなたのスクリプトの最初の行として追加:

#!/path/to/shell -f 

、スクリプトが実行権限をしていることを確認してください。あなたのシェルは/usr/binにインストールする必要はありません。 #!行にフルパスを指定するだけです。

あり/usr/bin/envハックでもあります:

#!/usr/bin/env shell 

はなく、多くのシステム上では、追加の引数を渡す許可していません。 (-fのない引数としてスクリプト名を使用するようにカスタムシェルを変更することを検討してください)#!/usr/bin/envの長所と短所をthis answerで議論しました。

#!メカニズムは、シェルではなく、カーネルによって処理されることに注意してください。

関連する問題