GNU/Linux >> Znalost Linux >  >> Linux

Jaká jsou pravidla pro platné identifikátory (např. funkce, vars atd.) v Bash?

Identifikátory příkazů a názvy proměnných mají různou syntaxi. Název proměnné je omezen na alfanumerické znaky a podtržítko, které nezačíná číslicí. Na druhou stranu název příkazu může být téměř cokoli, co neobsahuje metaznaky bash (a dokonce je lze citovat).

V bash mohou být názvy funkcí názvy příkazů, pokud by byly analyzovány jako SLOVO bez uvozovek. (Až na to, že z nějakého důvodu nemohou být celá čísla.) To je však rozšíření bash. Pokud cílový počítač používá nějaký jiný shell (jako je pomlčka), nemusí to fungovat, protože standardní gramatika shellu Posix povoluje pouze "NAME" ve formě definice funkce (a také zakazuje použití vyhrazených slov).


Otázka se týkala „pravidel“, která byla zodpovězena dvěma různými způsoby, z nichž každý je v určitém smyslu správný, v závislosti na tom, co chcete nazývat „pravidla“. Abych vysvětlil názor @rici, že ve jménu funkce můžete podstrčit jakýkoli znak, napsal jsem malý bash skript, který se pokusím zkontrolovat každý možný (0-255) znak jako název funkce, stejně jako druhý znak názvu funkce:

#!/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

Vlastně jsem přeskakoval NUL (0x00), protože to je jeden znak bash, který může mít námitky proti nalezení ve vstupním proudu. Výstup tohoto skriptu byl:

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!

Všimněte si, že bash mi naštěstí umožňuje pojmenovat moji funkci "[}{". Můj kodex pravděpodobně není dostatečně přísný, aby poskytoval přesná pravidla pro legalitu v praxi, ale měl by naznačit, jaký způsob zneužití je možný. Přál bych si tuto odpověď označit jako „Pouze pro dospělé.“


Z návodu:

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

name je definován jinde:

       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.

Pomlčky tedy neplatí. A přesto v mém systému fungují...

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

Linux
  1. Co jsou oddělovače slov Readline?

  2. Funkce v proměnných Shell?

  3. Jsou terminálové barevné únikové sekvence definovány kdekoli pro Bash?

  1. Odůvodnění Bash Shell vás nevaruje před aritmetickým přetečením atd.?

  2. Jaké jsou základní rozdíly mezi mainstreamovými *nix shelly?

  3. 7zip, Xz, Gzip, Tar, atd. – Jaké jsou rozdíly?

  1. Bash + Ověřit název regulárním výrazem?

  2. Bash Beginner Series #9:Použití funkcí v Bash

  3. Jaké jsou výhody CloudLinuxu?