bash loop

Hogyan tudnám loopolni a szkriptet saját magát?

Adott egy kis szkript mely kidob egy számozott listát, és kéri hogy válaszunk EGY számot. Ekkor végrehajtja a feladatot, és jelenleg kilép. Ha a 0 számot választjuk (ez nem szerepel a listában), akkor is kilép.

Ezt szeretném úgy megoldani hogy ne lépjen ki a feladat elvégzése után, hanem térjen vissza a kiinduló állapotba.
Csak akkor lépjen ki, ha 0-t írnak be.

Ismerem a "for" ciklust, a "while" ciklust, de ezek mindig egy feltételhez kötik a dolgot. Itt viszont nincs feltétel.
A "0" nem jó feltétel mert hierarchikusan nem ott helyezkedik el a szkriptben.

Hozzászólások

feltétel ugyebár ha igaz, akkor a ciklusban marad.
while true; do date; sleep 1; done
No és persze a break is a barátod.

Valóban. Köszi:


exit_out="0"
while true exit_out; do

prog code

if choice 0 then
exit_out=1
break
else
prog code
fi
done

Most nem láttam tovább az orromnál. Hiába... nem lehet egész nap kódolni. (No nem csak ezt!)
Már készen van a dvbrip felvevő cron, at időzítővel, és folyamatban van az rtc wake. Itt lesznek gondok...

De itt van a dvbTVportable végeredmény ha valaki hasznosítaná:

#!/bin/bash
# dvbTVportable interactive console mode digital tv viewer - 2017 (c)csablak
# License: GPLv3

exit_out="0"
while true exit_out; do

version="0.1"

# colors
Yellow="$(tput bold ; tput setaf 3)"
Cyan="$(tput bold ; tput setaf 6)"
NC="$(tput sgr0)" # Reset: No Color, offblink

channel_list="$HOME/.config/mpv/channels.conf.cbl" # Ez már szerkesztett lista! Sallangok, nem megfelelő írásjelek kivéve
dvb_player="mpv"
#dvb_player="mplayer" # Akadozik gl vagy vdpau, és lavf demux ellenére.

cat ${channel_list} | sed -e 's/ /_/g' | awk -vFS=":" '{printf("%02d %s\n", NR, $1)}' > $HOME/tmp/menu_list
channel_list="$HOME/tmp/menu_list"

index=1
while read line ; do
ch_name[$index]="${line}"
index=$(($index+1))
done < ${channel_list}

clear
echo -e "\n Welcome to console mode ${Yellow}dvbTV viewer ${version}!${NC}\n"
export GREP_COLOR='1;33'
column ${channel_list} | sed -e 's/_/ /g' | grep --color -P '[0-9]{2,3}' #s/\//-/g; s/\&/and/g;

printf "\n ${Yellow}Exit: 0 - ${Cyan}Choice the channel: "
read choice
if [ ${choice} = "0" ]; then
exit_out="0"
rm -f ${channel_list}
break
else
ch_name="${ch_name[${choice}]}"
ch_name=$(echo ${ch_name/${ch_name:0:3}} | awk -F ";" '{print $1}' | sed -e 's/_/ /g')
/usr/bin/$dvb_player --really-quiet dvb://"${ch_name}"
rm -f ${channel_list}
fi
done

Az én képességeimből ez sikerült. Autodidakta módon tanultam.
Ha valaki tud finomítani rajta az segíthet. Most legalább kiderül hogy hordozható-e?
parancssoros DVB-C, DVB-T néző nagy frontendek helyett.

EPG-t hogy lehetne belecsempészni?

Nincs a fenét :)
Felveszel a while előtt egy "kilep" nevű változót 0 értékkel, és ezt vizsgálod a while feltételeként, hogy amíg ez nulla, addig belép a ciklusba. A bevitt karaktert valahol nyilván megvizsgálod, ha ott 0 az input, akkor a kilep nevű változódat 1-re állítod, így legközelebb kilép a while-nál.

Szerk: vagy break, ha jól emlékszem ez is működhet :

while true; do
...
if [ "0" == inputvar ]; then
break
fi
done

Azért shell-ben egy végtelen while ciklus első elemeként egy kilépést tesztelő if durván ocsmány megoldás. Szóval amit írtál azt kevésbé trehány módon így kéne megírni


while [ "0" != inputvar ] ; do
...
done

Szerintem minimum $inputvar (meg akkor már inkább nem a feltételt negálnám, hanem while helyett until ciklussal írnám), de nem azon van a hangsúly.

=====
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?

Köszi Zahy! De mint említettem nem tanultam programozást. Mindenesetre ma is tanultam valamit.
Ki is javítottam untilra.

uzsolt
A cat -n nem vált be amikor próbáltam, mert 4 karakternyi üres helyet hagy a számok előtt, illetve nem 01, 02 hanem csak 1, 2
s így felborul a rendezett oszlop. Az awk NR számlálója írja be a számsorokat. A columnak meg így pont jó.

Vegtelen ciklus lesz a baratod, amibol, ha 0-t irtak be, kibreakelsz.


while (true) {
   ... read input ...
   if (input == '0') {
     break;
  }
}

Bashul nem tudok, ugyhogy a fenti csak pszeudo.

> Hogyan tudnám loopolni a szkriptet saját magát?
A feladatleírás alapján nem a szkriptet magát kell loopolni, hanem inkább a szkripten belül egy loop-ot létrehozni (ahogy fentebb a példákat mutatták).

Gondolom, ez egy menü-szerűség lenne. Egy ilyet úgy csináltam, hogy maga a menü egy függvény, aminek csak a kilépés menüpontra nem nulla a visszatérési értéke, és ez van a while-do-ban. Röviden valami ilyesmi:

#!/bin/sh

menu() {
  read ch
  case ${ch} in
    ...
    q) return 1
    ;;
  esac
}

while menu; do
done

Mondjuk a menu() függvényen belül a dialog parancsot használom (kicsit dizájnosabb, meg talán kisebb a téves felhasználói input lehetősége), de a lényegen nem változtat.

Fentiekkel ellentétben javasolnám azt a shell konstrukciót, amit pontosan erre találtak ki: neve "select" és egy ciklusszervező művelet. Addig rakja ki a listát, amíg nem utasítjuk az ellenkezőjére. Példa:


PS3='Válassz egy számot: '
select i in exit "ez meg az" amaz ; do
case "$i" in
"exit" ) break ;; # vagy break, ekkor csak a ciklusból, nem az egész scriptből lép ki
'ez meg az' ) echo 'Ide rakjuk az "ez meg az" kiválasztásakor végrehajtandó műveleteket'
echo "A válasz az volt hogy $REPLY; ezzel kiválasztottuk \"$i\"-t" ;;
amaz ) echo 'A demóban ez a 3. elem volt' ;;
* ) echo "Rossz válasz: $REPLY; i értéke: $i;" ;;
esac
echo 'Itt csinálhatunk olyasmit, amit minden esetben kell, a választástól függetlenül'
done # itt a select ciklus vége
echo 'Ide ugrunk, ha a "case" legelső ágában "break" van "exit" helyett'
exit # itt a demo vége

Sok sikert!

=====
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?

Rendben. Értem, de eddig sajna nem tökéletes.
Kipróbáltam ezt az awk-os sort.
Ehhez először kreáltam egy olyan menu.lst-et, melyben nincsenek számok, és a szóközök helyett alsó vonás van. Tehát jelenleg a lista annyiból áll hogy egymás alatt vannak a csatorna nevek.

Ha parancssorban futtatom csak ezt az awk-os sort, akkor 4 oszlopos formában jelenik meg a SZÁMOZOTT lista, de például
a "select choice in"-t ki sem írja.
Ha beleteszem a szkriptbe, akkor már csak 2 oszlop, és lefut a képernyőről.
Illetve szeretném színezni a számozást, és eltüntetni a zárójeleket, és az alsó vonásokat.
Meg azt is írják hogy az eval veszélyes parancs. Én nem vagyok programozó.