Nefunkční proměnná v BASH scriptu

Nefunkční proměnná v BASH scriptu
« kdy: 01. 03. 2023, 14:11:24 »
Ahoj, laboruju se skriptem v bashi ve kterém se snažím třídit databázový soubor. Třídění mi funguje, ale překvapilo mě chování proměné "OPAKOVAT"

Kód: [Vybrat]
#!/bin/bash
exit_status=0

while true; do
  OPAKOVAT=0
 
  find /opt/databaze_pracovni  -name "database.db" -exec sh -c '
     for file do
       dir=${file%/*}
       echo "$dir"
       /home/irma/database_sort_new "$dir"       
     OPAKOVAT=1 
     done' sh {} +
 
  echo $OPAKOVAT
  if [ $OPAKOVAT -eq 1 ]; then
      echo "nebude se uspavat"
      continue
  fi
 
  echo "sleep"
  sleep 300s
done

Zjistil jsem, že proměná "OPAKOVAT" se mi na konci skriptu nikdy nevyhodnotí jako "1" a to i přes to, že vždy najdu několik databázových souborů takže cyklus vždy proběhne. Můžete mi prosím někdo poradit co dělám špatně? Dík
« Poslední změna: 01. 03. 2023, 14:57:38 od Petr Krčmář »


czipis

  • ****
  • 252
    • Zobrazit profil
    • E-mail
Re:nefunkční proměná v BASH scriptu
« Odpověď #1 kdy: 01. 03. 2023, 14:42:35 »
protoze to OPAKOVAT=1 volate v novem shellu (exec sh -c) a to je pouze lokalni pro dany shell a vysledek se vam nedostane mimo ten for cyklus.

Re:nefunkční proměná v BASH scriptu
« Odpověď #2 kdy: 01. 03. 2023, 15:00:47 »
Super...dík za radu. To ale rozhodně nebyl můj záměr. Když jsem ten script tvořil tak jsem prostě googlil a zkoušel různý věci aby to dělalo to co potřebuji a je to několik let zpátky. Nyní potřebuji s tím zas něco jiného a nestačím se divit :-)

Tak se zeptám ještě na jednu věc....jak z toho ven, resp. lze to nějak jednoduše upravit nebo je potřeba znovu zapátrat?
Dík.

k3dAR

  • *****
  • 3 192
  • porad nemam telo, ale uz mam hlavu... nobody
    • Zobrazit profil
    • E-mail
Re:Nefunkční proměnná v BASH scriptu
« Odpověď #3 kdy: 01. 03. 2023, 15:24:09 »
pokud mi neco neunika, tak ten find odstavec resit normalne=obracene :-)

Kód: [Vybrat]
while read file; do
dir=${file%/*}
echo "${dir}"
/home/irma/database_sort_new "${dir}"
OPAKOVAT=1
done < <(find /opt/databaze_pracovni -name "database.db")

FKoudelka

Re:Nefunkční proměnná v BASH scriptu
« Odpověď #4 kdy: 01. 03. 2023, 18:53:39 »
pusť to s pomocí sh -x na debug
taky export OPAKOVAT by neškodil
« Poslední změna: 01. 03. 2023, 18:57:38 od FKoudelka »


FKoudelka

Re:nefunkční proměná v BASH scriptu
« Odpověď #5 kdy: 01. 03. 2023, 18:59:17 »
protoze to OPAKOVAT=1 volate v novem shellu (exec sh -c) a to je pouze lokalni pro dany shell a vysledek se vam nedostane mimo ten for cyklus.
ano, jsou to defacto dvě různé proměnné.

FKoudelka

Re:Nefunkční proměnná v BASH scriptu
« Odpověď #6 kdy: 01. 03. 2023, 19:01:29 »
pusť to s pomocí sh -x na debug
taky export OPAKOVAT by neškodil
https://www.baeldung.com/linux/bash-variables-export

FKoudelka

Re:Nefunkční proměnná v BASH scriptu
« Odpověď #7 kdy: 01. 03. 2023, 22:37:04 »
zkusil jsem zase chatgpt :-) ne že bych to měl zapotřebí :-) ani jsem to netestoval

a koukám, že už to psal k3dar

Problém je v tom, že hodnota proměnné OPAKOVAT se nastaví uvnitř podshellu, který je spuštěn pomocí příkazu sh -c. Proměnná OPAKOVAT v této podobě existuje pouze v kontextu podshellu a změna hodnoty se neodráží na proměnné OPAKOVAT v nadřazeném shellu.

Jednou z možností, jak toto řešit, je použít přímý způsob komunikace mezi podshellem a nadřazeným shellem pomocí standardního výstupu a standardního vstupu. Můžete to provést následovně:

Kód: [Vybrat]
#!/bin/bash

declare -i OPAKOVAT=0
exit_status=0

while true; do
  OPAKOVAT=0

  while read -r dir; do
    echo "$dir"
    /home/irma/database_sort_new "$dir"
    OPAKOVAT=1
  done < <(find /opt/databaze_pracovni -name "database.db" -exec dirname {} \;)

  echo $OPAKOVAT
  if [ $OPAKOVAT -eq 1 ]; then
      echo "nebude se uspavat"
      continue
  fi

  echo "sleep"
  sleep 300
done
Tento skript používá konstrukci < <() pro spuštění podshellu, který získává seznam adresářů obsahujících soubor database.db. Tento seznam je předán do cyklu while pomocí standardního vstupu, kde se každý adresář zpracovává a nastavuje se proměnná OPAKOVAT.
« Poslední změna: 01. 03. 2023, 22:43:14 od FKoudelka »

Re:Nefunkční proměnná v BASH scriptu
« Odpověď #8 kdy: 02. 03. 2023, 07:49:23 »
pokud mi neco neunika, tak ten find odstavec resit normalne=obracene :-)

Kód: [Vybrat]
while read file; do
dir=${file%/*}
echo "${dir}"
/home/irma/database_sort_new "${dir}"
OPAKOVAT=1
done < <(find /opt/databaze_pracovni -name "database.db")

Asi ti nic neuniklo....toto funguje. Dík za pomoc, protože tohle mi ušetří spoustu nervů :-)