Řešení chyb ve skriptech

Řekněme, že máme následující skript:

  #!/bin/bash
  
  PROMENNA="dve slova"               
  
  if [ -z $PROMENNA ]; then
    echo "Promenna je prazdna."
  else
    echo "Promenna obsahuje $PROMENNA"
  fi

Pokud ho spustíme, dostaneme následující hlášku:

  skript: line 5: [: dve: binary operator expected

Problém nastal na řádce 5 (tj. na řádce z podmínkou). Jelikož proměnná, kterou testujeme, obsahuje dvě slova oddělená mezerou a po dosazení proměnné do podmínky při běhu skriptu se tato mezera interpretuje jako oddělovač, otestuje se pouze řetězec „dve“ a řetězec „slova“ se Bash pokusí mylně interpretovat jako další část podmínky:

  if [ -z dve slova ]; then

Tento problém lze odstranit uzavřením proměnné do uvozovek:

  if [ -z "$PROMENNA" ]; then

Pak, po dosazení proměnné se Bash dopracuje k výrazu, kde „uvidí“ pouze jediný řetězec:

  if [ -z "dve slova" ]; then

Uzavření proměnné do uvozovek pomůže třeba i v situaci, kdy je příslušná proměnná prázdná. Další problém může nastat velmi snadno v případě, kdy je proměnná nesprávného typu. I když jsou v Bashi všechny proměnné považovány za řetězce, v některých případech může Bash očekávat pouze určité znaky. Třeba v situaci, kdy testujeme nějakou číselnou hodnotu, očekává Bash řetězec složený pouze z čísel:

  #!/bin/bash
  
  CISLO="ahoj"
  
  if [ "$CISLO" -eq 5 ]; then
     echo "Cislo je rovne 5."
  else
     echo "Cislo neni rovne 5."
  fi

V tomto případě dostaneme hlášku:

  skript: line 5: [: ahoj: integer expression expected

Tou se vám Bash snaží naznačit, že tam, kde očekával číslo, číslo není. V tomto případě můžeme před touto podmínkou testovat příslušnou proměnnou pomocí regulárních výrazů, zda-li obsahuje pouze čísla. Většinou ale postačí, pokud si tuto záležitost pouze sami ohlídáte.

Další velmi typickou chybou je zapomenutí nějaké párové značky, třeba uvozovek:

  #!/bin/bash
  PROMENNA="ahoj
  if [ -z "$PROMENNA" ]; then
     echo "Promenna je prazdna."
  else
     echo "$PROMENNA"
  fi

Po spuštění tohoto skriptu nám Bash zahlásí:

  ./skript: line 7: unexpected EOF while looking for matching `"'
  ./skript: line 9: syntax error: unexpected end of file

V tomto případě nezbyde než problém najít a odstranit. V delších skriptech vám pomohou editory s barevným zvýrazněním syntaxe.

Ne vždycky ale bude chyba zcela zřejmá. Může se stát, že nebude zřejmé, kde přesně chyba nastala. Pak můžete použít parametr -x, buď takto:

  bash -x skript

Nebo umístěte do záhlaví skriptu lehce pozměněnou úvodní řádku:

  #!/bin/bash -x

Tak nám Bash bude vypisovat průběh skriptu. Můžeme takto označit třeba jen některou část skriptu:

  #!/bin/bash
  
  CISLO="ahoj"
  
  set -x
  
  if [ "$CISLO" -eq 5 ]; then
     echo "Cislo je rovne 5."
  else
     echo "Cislo neni rovne 5."
  fi
  
  set +x
  
  [...]

Jiným trikem je třeba zakomentování nějakého podezřelého úseku:

  #!/bin/bash
  
  CISLO="ahoj"
  if [ "$CISLO" -eq 5 ]; then
     echo "Cislo je rovne 5."
  #else
  #   echo "Cislo neni rovne 5."
  fi

Pokud pracujeme s nějakým nebezpečným programem, můžeme při ladění skriptu nechat použití inkriminovaného programu nechat vypisovat:

  #!/bin/bash
  
  cp /var/log/messages /tmp
  echo rm /tmp/messages

Což se bude hodit ještě více, pokud danému nebezpečnému programu budete předhazovat nějakou proměnnou, kde s jistotou nevíte, co se v ní bude v danou chvíli nacházet.

Kam dál

pokrocili/komandlajna/reseni_chyb.txt · Poslední úprava: 2009/11/12 19:32 autor: Michal Dočekal
CC Attribution-Share Alike 3.0
www.chimeric.de Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0 PDF Export