GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Unterschiede zwischen reserviertem Wort und Befehl "Zeit" in Shell Builtin, Funktion, Pipeline und Befehlsliste?

Im Bash-Referenzhandbuch

Die Verwendung von time als reserviertes Wort erlaubt das Timing von shell builtins , Shell-Funktionen und Pipelines . Eine externe
time Befehl kann diese nicht einfach timen.

  1. Können Sie erklären, warum das Zitat das sagt?

    Liegt das an dem Unterschied zwischen einem reservierten Wort und einem
    Befehl, nicht nur beschränkt auf den Fall time ? Wie werden sie zum Beispiel von der Bash-Shell
    analysiert oder anders interpretiert?

    Oder ist dies nur auf den Fall time beschränkt ?

  2. In den folgenden Beispielen

    warum funktioniert die externe time Arbeit an einer eingebauten Shell und einer
    Pipeline, während das Zitat sagt, dass es "diese nicht einfach timen kann"?

    Externe time auf einer eingebauten Shell :

    $ /usr/bin/time echo hello
    hello
    0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 1676maxresident)k
    0inputs+0outputs (0major+78minor)pagefaults 0swaps
    

    Externe time auf einer Pipeline :

    $ /usr/bin/time sleep 10 | sleep 5
    0.00user 0.00system 0:10.00elapsed 0%CPU (0avgtext+0avgdata 1776maxresident)k
    0inputs+0outputs (0major+79minor)pagefaults 0swaps
    
  3. Warum funktioniert im folgenden Beispiel die externe time auf einer Shell
    -Funktion
    scheitern? Was bedeutet seine Fehlerausgabe?

    $ function mytest () { sleep 10; }
    
    $ /usr/bin/time mytest
    /usr/bin/time: cannot run mytest: No such file or directory
    Command exited with non-zero status 127
    0.00user 0.00system 0:00.03elapsed 0%CPU (0avgtext+0avgdata 1252maxresident)k
    32inputs+0outputs (0major+30minor)pagefaults 0swaps
    
  4. Anscheinend gilt das Zitat nicht nur für das Timing von Shell-Builtins,
    Shell-Funktionen und Pipelines, sondern auch für das Timing einer Gruppe von
    Befehlen
    :

    $ time { echo hello; sleep 3; echo tim; }
    hello
    tim
    
    real    0m3.002s
    user    0m0.000s
    sys 0m0.000s
    
    
    $ /usr/bin/time { echo hello; sleep 3; echo tim; }
    bash: syntax error near unexpected token `}'
    

    Warum sagt die Shell „bash:Syntaxfehler nahe unerwartetem Token
    } ” im Fall des Befehls /usr/bin/time ?

Akzeptierte Antwort:

In bash , time ist ein reserviertes Wort, also kann die Shell es auf eigene Weise parsen und Regeln dafür anwenden.

Hier ist der Code, der zeigt, wie bash Parse-Zeile beginnt mit time Reserviertes Wort:

static int
time_command_acceptable ()
{
#if defined (COMMAND_TIMING)
  int i;

  if (posixly_correct && shell_compatibility_level > 41)
    {
      /* Quick check of the rest of the line to find the next token.  If it
     begins with a `-', Posix says to not return `time' as the token.
     This was interp 267. */
      i = shell_input_line_index;
      while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == 't'))
        i++;
      if (shell_input_line[i] == '-')
    return 0;
    }

  switch (last_read_token)
    {
    case 0:
    case ';':
    case 'n':
    case AND_AND:
    case OR_OR:
    case '&':
    case WHILE:
    case DO:
    case UNTIL:
    case IF:
    case THEN:
    case ELIF:
    case ELSE:
    case '{':       /* } */
    case '(':       /* )( */
    case ')':       /* only valid in case statement */
    case BANG:      /* ! time pipeline */
    case TIME:      /* time time pipeline */
    case TIMEOPT:   /* time -p time pipeline */
    case TIMEIGN:   /* time -p -- ... */
      return 1;
    default:
      return 0;
    }
#else
  return 0;
#endif /* COMMAND_TIMING */
}

Sehen Sie, time kann von den meisten anderen bash gefolgt werden reservierte Wörter.

Verwandte:OS X Time Machine unter Linux entschlüsseln?

Im Falle eines externen Befehls wurde die normale Regel angewendet, { wurde als Eingabe von /usr/bin/time betrachtet . } allein ist ungültiges Token und bash den Fehler melden.

In:

/usr/bin/time echo hello

externe time hat das in die Shell eingebaute echo nicht aufgerufen sondern das externe echo Befehl.

Eine strace bestätigt das:

$ strace -fe execve /usr/bin/time echo 1
execve("/usr/bin/time", ["/usr/bin/time", "echo", "1"], [/* 64 vars */]) = 0
Process 25161 attached
....
[pid 25161] execve("/usr/bin/echo", ["echo", "1"], [/* 64 vars */]) = -1 ENOENT (No such file or directory)
[pid 25161] execve("/bin/echo", ["echo", "1"], [/* 64 vars */]) = 0
1
[pid 25161] +++ exited with 0 +++
....

Hier externe time Suchen Sie Ihren PATH Variable, um die ausführbare Befehlsdatei zu finden. Das erklärt auch, wenn Sie eine Funktion verwenden, erhalten Sie keine solche Datei oder kein solches Verzeichnis weil es keinen Befehl namens mytest gibt in Ihrem PATH .


Linux
  1. Der Unterschied zwischen einem eingebauten Befehl und einem, der es nicht ist?

  2. Unterschiede zwischen Volume, Partition und Laufwerk?

  3. Unterschiede zwischen Sed auf Mac Osx und anderen „Standard“-Sed?

  4. Unterschied zwischen CLOCK_REALTIME und CLOCK_MONOTONIC?

  5. Sub-Shell-Unterschiede zwischen bash und ksh

25 Fragen und Antworten zum Linux-Shell-Scripting-Interview

Ls-Befehl in Linux (Dateien und Verzeichnisse auflisten)

So listen Sie Benutzer und Gruppen unter Linux auf

Vim vs. Vi – Ähnlichkeiten und Unterschiede zwischen VIM und VI?

Unterschied zwischen '{}' und {} im Find-Befehl?

Unterschied zwischen cp -r und cp -R (Kopierbefehl)