Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Téma založeno: filip2cz 02 Června 2022, 19:28:11
-
Zdravím, vytvořil jsem si skript, který pomocí ncatu očekává jednou za čas vstup a pokud ho nedostane, tak tuhle informaci přes curl předá dále. Nicméně tento skript někdy funguje a někdy ne, respektive funguje mi na Ubuntu serveru a notebooku s PopOS, kde jsem ho vyvíjel, ale nefunguje na OrangePi s Armbian a ani na jiném serveru s openSUSE. Skript přikládám zde: https://github.com/filip2cz/ntfy-server-status/blob/main/ntfy-netcat/ntfy-netcat-server
error, který to případně píše je: /home/filip/ntfy/ssfs/ntfy-ssfs-server: line 16: ((: == 1: syntax error: operand expected (error token is "== 1")
Nenapadá někoho něco, čím to je, případně jak to opravit?
-
Tvůj kód: if (($status == 1)); then
si myslím, že by měl vypadat takto: if [[$status -eq 1]]; then
-
Sypu si popel na hlavu. Takto je to správně: if [ $status = 1 ]; then
-
Asi čistější by bylo použít if [ $status -eq 1 ]; then
Ač je $status řetězec mám pocit, že vnitřně je převeden na číslo. A numerické hodnoty by se měli porovnávat pomocí -eq
-
Sypu si popel na hlavu. Takto je to správně: if [ $status = 1 ]; then
na openSUSE serveru stejný error:
/home/filip/ntfy/ntfy-ssfs: řádek 16: [: =: očekáván unární operátor
-
Asi čistější by bylo použít if [ $status -eq 1 ]; then
Ač je $status řetězec mám pocit, že vnitřně je převeden na číslo. A numerické hodnoty by se měli porovnávat pomocí -eq
Taky jsem zkusil, stejný problém
./ntfy-ssfs: řádek 16: [: -eq: očekáván unární operátor
-
if [[ $status = "1" ]]; then Ncat nepoužívám předpokládám, že vracená hodnota bude string
-
if [[ $status = "1" ]]; then Ncat nepoužívám předpokládám, že vracená hodnota bude string
tohle už nehází ten error, ale nepropíše se to do proměnné
-
Nerozumím co znamená "nepropíše se to do proměnné"
Celému skriptu nějak moc nerozumím.
Nejdřív testuješ proměnnou status na základě výstupu z ncatu. Pokud je to ok, tak testuješ proměnnou log. Pokud se log rovná nule má to vypsat to hlášku a do log zapíše jedničku. Avšak pokud se log rovná něčemu jinému než nule, nevykoná se vůbec nic a hodnota log zůstává do konce života skriptu nezměněna! Tímto to končí zápisem null do status ať bude log jakýkoliv.
Pakliže je na začátku smyčky status neroven jedničce, skočí to na větev kde se porovnává log s jedničkou. A to je asi špatně z logiky věci. Protože pokud by log byl cokoliv jiného než jedna tak se nic neděje. Myslím, že máš podmínky nastavené ve špatných větvích. Plus syntaktické chyby v condition if. Mám pochyby o tom, že to vůbec fungovalo jak jsi zamýšlel.
-
Jsi si trochu přesunul ten kód na https://github.com/filip2cz/ntfy-server-status/blob/main/netcat-server-sending/ntfy-netcat-server
Pořádně jsem si to prohlédl a myslím, že vím čeho jsi chtěl dosáhnout. Tak jsem ti základní engine přepsal a zbytek si tam dopiš dle svého uvážení:
#! /usr/bin/env bash
LOGZAP="ano"
LOGVYP="ano"
LOCALSERVERPORT=4444
while :
do
STATUS=
STATUS=`timeout 5s nc -l -w 1 -p $LOCALSERVERPORT`
if [[ $STATUS ]]; then
if [[ $LOGZAP ]]; then
echo spustil se server
LOGZAP=
LOGVYP=ano
# sem si dej kód/logování o spuštění serveru
fi
HLASKA="Jede to"
# sem patří kód když server běží
else
if [[ $LOGVYP ]]; then
echo zastavil se server
LOGVYP=
LOGZAP=ano
# sem si dej kód/logování o zastavení serveru
fi
HLASKA="Nejede to"
# sem patří kód když server neběží
fi
echo $HLASKA
done
Odzkoušeno a jede to na 100%. Ono je trochu ošemetné psát scripty v bash. On má totiž bash takovou svou divnou logiku a člověk musí na to tak nějak pořád dbát a myslet. Třeba, že všechny proměnné jsou v bash řetězce! Takže nemá moc cenu testovat jaká je návratová hodnota, ale zda vůbe nějaká je. Je to rychlejší a méně náročné na systémové prostředky:
na openSUSE serveru stejný error:
/home/filip/ntfy/ntfy-ssfs: řádek 16: [: =: očekáván unární operátor
Třeba tady je návratová hodnota nic a to nic se chce matematicky porovnat s jedničkou. Bash si myslel, že se jedná o unární operátor. V mém scriptu používám unární operátory a to ještě v tom nejzákladnějším původním smyslu (tak trochu booleova logika), buď to je anebo není.
Dále systém dereferencí a substitucí je kolikrát taky na bednu. Pokud člověk nedělá v bash dost často, tak to bývá u rozsáhlejších projektů peklo. Hlavně pokud píše něco v jiných jazycích a pak se přepnout na bash logiku je kumšt. Osobně když něco potřebuji, tak si to většinou sesmolím v pythonu.
Měj se fajn a přeju mnoho úspěchů v učení programovacích jazyků.
-
Jsem se nudil. A už půlroku nenapsal nic kde bych z pythonu přistupoval k síťovým prvkům https://github.com/RadekRojik/minilista/blob/master/net.py Aby mi nechcípl mozek tak jsem si pohrál a přepsal základní funkčnost Tvého scriptu do pythonu. Vždy se snažím používat jen základní pythoní knihovny:
#! /usr/bin/env python3
import socket
import select
class Nc_client:
""" třída vyžaduje konstrukční parametry host a port """
def __init__(self, host: socket.AF_INET, port: int):
# veřejný atribut host, jde dodatečně měnit
self.host = host
# veřejný atribut port, jde dodatečně změnit
self.port = port
# veřejný atribut timeout jde také změnit z venku.
# timeout by neměl být menší než perioda vysílání serveru
# jinak bude třída vracet, že server neběží. Jinak řečeno,
# třída by neměla být rychlejší než je vysílání serveru
self.timeout = 3
def _run(self):
""" metoda vytvářející socket a spojení s ním
dal jsem jí zvlášť mimo init aby se dali měnit veřejné atributy
před vytvořením socketu a zároveň na opakované využití při
tvorbě nových metod """
# vytvoření socketu
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# socket nastavíme na opakované použití
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# navázání spojení se socketem předáním n-tice (páru)
self.sock.bind((self.host, self.port))
# nastavení ať se socket neblokuje
self.sock.setblocking(False)
def server_bezi(self) -> bool:
""" metoda vracející jestli běží server či nikoli"""
# vytvoření a navázání spojení socketu
self._run()
# listování socketu
self.sock.listen(self.timeout)
# přednastavená návratová hodnota
navrat = False
# čtení ze selectu. Tím zamezíme čekání na nějaký
# návrat (zamrznutí scriptu)
vyst, vst, chyby = select.select([self.sock], [], [], self.timeout)
# procházení výstupu ze selectu
for vy in vyst:
# test či je výstup schodný s námi otevřeným socketem
if vy is self.sock:
# máme spojení, to znamená, že server běží. Nepotřebujem znát
# co server vysílá
navrat = True
# uzavření socketu, ať se nám nehromadí otevřené prostředky a
# nechtěné chyby
self.sock.close()
return navrat
# vytvoření testovací instance třídy - objektu
testik = Nc_client("localhost", 4444)
# timeout jde po vytvoření instance donastavit, např:
testik.timeout = 5
# test metody objektu
print(testik.server_bezi())
Více a podrobněji zde: https://docs.python.org/3.8/library/socket.html#module-socket
Hodně si věci komentuju, protože co je mi v té chvíli jasné nad slunce. Už za týden nechápu a říkám si co jsem tím ku... myslel. ;D
-
Díky za vaše odpovědi, nakonec jsem to vyřešil trochu jinak a používám C alternativu k netcadu, kterou sepsal jeden můj známý.
Díky za vaše kódy, rozhodně vypadají zajímavě.