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

Welche Regeln gelten für gültige Bezeichner (z. B. Funktionen, Variablen usw.) in Bash?

Befehlsbezeichner und Variablennamen haben unterschiedliche Syntaxen. Ein Variablenname ist auf alphanumerische Zeichen und Unterstriche beschränkt und darf nicht mit einer Ziffer beginnen. Andererseits kann ein Befehlsname so ziemlich alles sein, was keine Bash-Metazeichen enthält (und selbst dann können sie in Anführungszeichen gesetzt werden).

In Bash können Funktionsnamen Befehlsnamen sein, solange sie als WORD ohne Anführungszeichen geparst würden. (Abgesehen davon, dass sie aus irgendeinem Grund keine ganzen Zahlen sein können.) Dies ist jedoch eine Bash-Erweiterung. Wenn der Zielcomputer eine andere Shell verwendet (z. B. Bindestrich), funktioniert dies möglicherweise nicht, da die Posix-Standard-Shell-Grammatik nur "NAME" in der Funktionsdefinitionsform zulässt (und auch die Verwendung reservierter Wörter verbietet).


Die Frage betraf "die Regeln", die auf zwei verschiedene Arten beantwortet wurde, jede in gewissem Sinne richtig, je nachdem, was Sie "die Regeln" nennen möchten. Nur um @ricis Argument zu verdeutlichen, dass Sie jedes Zeichen in einem Funktionsnamen herumschieben können, habe ich ein kleines Bash-Skript geschrieben, um es zu überprüfen jedes mögliche (0-255) Zeichen als Funktionsname, sowie das zweite Zeichen eines Funktionsnamens:

#!/bin/bash
ASCII=( nul soh stx etx eot enq ack bel bs tab nl vt np cr so si dle \
            dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us sp )

for((i=33; i < 127; ++i)); do
    printf -v Hex "%x" $i

    printf -v Chr "\x$Hex"
    ASCII[$i]="$Chr"
done
ASCII[127]=del
for((i=128; i < 256; ++i)); do
    ASCII[$i]=$(printf "0X%x" $i)
done

# ASCII table is now defined

function Test(){
    Illegal=""
    for((i=1; i <= 255; ++i)); do
        Name="$(printf \\$(printf '%03o' $i))"
        eval "function $1$Name(){ return 0; }; $1$Name ;" 2>/dev/null
        if [[ $? -ne 0 ]]; then
            Illegal+=" ${ASCII[$i]}"
            #        echo Illegal: "${ASCII[$i]}"
        fi
    done
    printf "Illegal: %s\n" "$Illegal"
}
echo "$BASH_VERSION"
Test
Test "x"

# can we really do funky crap like this?
function [}{(){
   echo "Let me take you to, funkytown!"
}
[}{    # why yes, we can!
# though editor auto-indent modes may punish us

Ich überspringe tatsächlich NUL (0x00), da dies das einzige Zeichen ist, das Bash möglicherweise im Eingabestrom findet. Die Ausgabe dieses Skripts war:

4.4.0(1)-release
Illegal:  soh tab nl sp ! " # $ % & ' ( ) * 0 1 2 3 4 5 6 7 8 9 ; < > \ ` { | } ~ del
Illegal:  soh " $ & ' ( ) ; < > [ \ ` | del
Let me take you to, funkytown!

Beachten Sie, dass bash mich gerne meine Funktion "[}{" nennen lässt. Wahrscheinlich ist mein Code nicht ganz streng genug, um die genauen Regeln für die Legalität in der Praxis bereitzustellen, aber er sollte einen Eindruck davon vermitteln, welche Art von Missbrauch möglich ist. Ich wünschte, ich könnte diese Antwort mit "Nur für erwachsenes Publikum" markieren. P>

Aus dem Handbuch:

   Shell Function Definitions
       ...
       name () compound-command [redirection]
       function name [()] compound-command [redirection]

name ist an anderer Stelle definiert:

       name   A  word  consisting  only  of alphanumeric characters and under‐
              scores, and beginning with an alphabetic character or an  under‐
              score.  Also referred to as an identifier.

Bindestriche sind also nicht gültig. Und doch funktionieren sie auf meinem System...

$ bash --version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)

Linux
  1. Funktionen in Shell-Variablen?

  2. Sind die Terminal-Farb-Escape-Sequenzen irgendwo für Bash definiert?

  3. Bash + Name durch regulären Ausdruck überprüfen?

  4. 7zip, Xz, Gzip, Tar usw. — Was sind die Unterschiede?

  5. Bash-Anfängerserie Nr. 9:Verwenden von Funktionen in Bash

Bash-Funktionen

Shell-Scripting Teil V:Funktionen in Bash

Die Bash FOR-Schleife erklärt und vereinfacht

Was sind die Aufrufkonventionen für UNIX- und Linux-Systemaufrufe (und User-Space-Funktionen) auf i386 und x86-64

Was ist die Verwendung von $ # in Bash

Welche Funktionen hat das BIOS bei laufendem Betriebssystem?