27.10.2026

Kaip naudoti Linux Shell įrankius Progress OpenEdge aplinkoje

Progress OpenEdge sukurta našiam operacijų apdorojimui, tačiau ji niekada nebuvo skirta veikti kaip Unix komandų „shell“ (liet. apvalkalas). Kai Progress OpenEdge programoms reikia paleisti atsarginių kopijų scenarijus, ETL užduotis ar tvarkyti didelius žurnalų failus, programuotojai turi išeiti už ABL virtualiosios mašinos (AVM) ribų. Būtent čia dažnai ir prasideda problemos.

Šiame blogo įraše dalinuosi dviem patikrintais sprendimais iš savo darbo su Progress OpenEdge. Sužinosite, kaip pastebėti „shell“ scenarijų klaidas, kurias paslepia OS-COMMAND. Taip pat parodysiu, kaip filtruoti ir rotuoti kelių gigabaitų žurnalus, neįkeliant jų į AVM atmintį ir neperkraunant duomenų bazės brokerio.

Kodėl OS-COMMAND paslepia „shell“ scenarijų klaidas Progress OpenEdge aplinkoje?

OS-COMMAND paslepia klaidas, nes negrąžina scenarijaus išėjimo kodo (angl. exit code) ir išmeta viską, ką scenarijus įrašo į standartinį klaidų srautą (stderr). Jei scenarijus nutrūksta pusiaukelėje dėl pilno disko ar trūkstamų teisių, ABL tiesiog vykdo kitą kodo eilutę, lyg nieko nebūtų nutikę.

Įprastas iškvietimas atrodo taip:

‍

OS-COMMAND VALUE("myscript.sh"). 

Išėjimo kodas – tai skaičius, kurį programa grąžina baigusi darbą: 0 reiškia sėkmę, o bet kuris kitas skaičius rodo klaidą. Stderr – tai kanalas, kuriuo dauguma scenarijų siunčia klaidų pranešimus. Be šių dviejų dalykų nepavykusi atsarginė kopija atrodo lygiai taip pat kaip sėkminga. Daugiau apie šio sakinio veikimą rasite Progress Community straipsnyje apie OS-COMMAND, „shell“ scenarijus ir PASOE.

Kaip gauti išėjimo kodus ir klaidas su INPUT THROUGH?

Sprendimas – vietoje OS-COMMAND naudoti INPUT THROUGH, kuris leidžia ABL skaityti komandos išvestį eilutė po eilutės. Kad tai veiktų patikimai, stderr reikia sujungti su įprasta išvestimi, o baigus scenarijų išspausdinti išėjimo kodą pažymėtoje eilutėje. Tada ABL gali perskaityti ir klaidų pranešimus, ir tikrąjį rezultatą.

Progress šį klausimą taip pat aptaria gide, kaip gauti „shell“ scenarijaus grąžinamą reikšmę. Reikia dviejų dalykų:

  1. Sujungti stderr su standartine išvestimi (stdout) naudojant „shell“ peradresavimą 2>&1, kad klaidų pranešimai nedingtų.
  2. Iškart po scenarijaus išspausdinti išėjimo kodą su žyme, kurios nebūtų galima supainioti su tikra išvestimi. Taip išėjimo kodas, kurį žino tik „shell“, patenka į srautą, kurį skaito ABL.

Kaip veikia „shell“ komanda?

Visa „shell“ komanda vienoje eilutėje paleidžia scenarijų, peradresuoja jo klaidas ir išspausdina išėjimo kodą:

‍

/bin/sh -c "myscript.sh 2>&1 ; echo @@EXIT_CODE=$?" 

‍

  • /bin/sh -c "..." paleidžia „shell“ ir viską, kas kabutėse, vykdo kaip vieną komandų eilutę. To reikia, nes 2>&1, ; ir echo yra „shell“ sintaksė, kurios ABL pati nesupranta. ‍
  • myscript.sh – paleidžiamas scenarijus. ‍
  • 2>&1 sujungia failo deskriptorių 2 (stderr) su failo deskriptoriumi 1 (stdout), todėl klaidų pranešimai patenka į tą patį srautą kaip ir įprasta išvestis. ‍
  • ; paleidžia kitą komandą bet kokiu atveju, todėl echo įvykdomas visada, nesvarbu, ar scenarijus pavyko, ar ne. ‍
  • echo @@EXIT_CODE=$? baigus scenarijų išspausdina dar vieną eilutę. $? saugo paskutinės komandos išėjimo kodą, o @@EXIT_CODE= yra sugalvota žymė, kuri vargu ar pasitaikys paties scenarijaus išvestyje.

Ką daro pavyzdinis atsarginių kopijų scenarijus?

Pavyzdinis scenarijus sampleScript.sh archyvuoja duomenų katalogą su tar. Jei tar neveikia, scenarijus išspausdina klaidą į stderr ir baigia darbą su kodu 10. Tiktų bet kuris nenulinis skaičius, 10 – tik pavyzdys.

‍

#!/usr/bin/env bash 
set -euo pipefail 
 
BACKUP_DIR="/opt/app/backups" 
SOURCE_DIR="/opt/app/data" 
LOGFILE="/var/log/app/backup.log" 
 
mkdir -p "$BACKUP_DIR" 
echo "[$(date '+%F %T')] Starting nightly backup of $SOURCE_DIR" 
 
ARCHIVE="$BACKUP_DIR/data-$(date '+%Y%m%d').tar.gz" 
if tar -czf "$ARCHIVE" -C "$SOURCE_DIR" . ; then 
  echo "[$(date '+%F %T')] Archive written to $ARCHIVE" 
else 
  echo "ERROR: tar failed while archiving $SOURCE_DIR" >&2 
  exit 10 
fi 
 
echo "[$(date '+%F %T')] Pruning old archives, keeping 7 copies" 
ls -1t "$BACKUP_DIR"/data-*.tar.gz | tail -n +8 | xargs -r rm -f || true 
 
echo "[$(date '+%F %T')] Backup finished successfully" | tee -a "$LOGFILE" 
exit 0

‍

Kaip tarpinė procedūra runScript.p nuskaito išvestį?

Procedūra runScript.p gauna komandą, paleidžia ją per INPUT THROUGH ir grąžina išėjimo kodą kartu su visa komandos išvestimi. Jei išėjimo kodas nėra 0, procedūra iškelia ABL klaidą, užuot tyliai baigusi darbą.

‍

DEFINE INPUT  PARAMETER pcScript   AS CHARACTER NO-UNDO. /* full command */ 
DEFINE OUTPUT PARAMETER piExitCode AS INTEGER   NO-UNDO. 
DEFINE OUTPUT PARAMETER pcOutput   AS LONGCHAR  NO-UNDO. 
 
DEFINE VARIABLE cCmdLine   AS CHARACTER NO-UNDO. 
DEFINE VARIABLE cLine      AS CHARACTER NO-UNDO FORMAT "x(10000)". 
DEFINE VARIABLE cSentinel  AS CHARACTER NO-UNDO INITIAL "@@EXIT_CODE=". 
DEFINE VARIABLE cShellPath AS CHARACTER NO-UNDO. 
 
cShellPath = OS-GETENV("OE_SHELL_PATH"). 
IF cShellPath = ? OR cShellPath = "" THEN 
    cShellPath = "/bin/sh". 
 
cCmdLine = cShellPath + ' -c "' + pcScript + ' 2>&1 ; echo ' + cSentinel + '$? ' + '"'. 
 
INPUT THROUGH VALUE(cCmdLine) NO-ECHO UNBUFFERED. 
 
REPEAT ON ENDKEY UNDO, LEAVE: 
    IMPORT UNFORMATTED cLine. 
    IF cLine BEGINS cSentinel THEN DO: 
        piExitCode = INTEGER(SUBSTRING(cLine, LENGTH(cSentinel) + 1)). 
        NEXT. 
    END. 
    pcOutput = pcOutput + cLine + CHR(10). 
END. 
 
INPUT CLOSE. 
 
IF piExitCode NE 0 THEN 
    RETURN ERROR SUBSTITUTE("Shell command failed (exit &1)", piExitCode).

‍

Štai ką daro kiekviena dalis:

  • pcScript – paleidžiama komanda, pavyzdžiui, "./sampleScript.sh --mode nightly". piExitCode ir pcOutput užpildomi procedūrai vykstant. ‍
  • cShellPath nurodo, kurį „shell“ naudoti. Jei nenurodyta kitaip, naudojamas /bin/sh. ‍
  • cCmdLine sudaro visą komandą: <shell> -c "<scenarijus> 2>&1 ; echo <žymė>$?". ‍
  • INPUT THROUGH VALUE(cCmdLine) NO-ECHO UNBUFFERED paleidžia komandą ir jos išvestį skaito kaip srautą, panašiai kaip INPUT FROM skaito failą. NO-ECHO neleidžia ABL rodyti išvesties ekrane, o UNBUFFERED kiekvieną eilutę nuskaito vos tik ji atsiranda. ‍
  • REPEAT ON ENDKEY UNDO, LEAVE skaito po vieną eilutę ir, pasibaigus įvesčiai, ciklą užbaigia be klaidos. ‍
  • IMPORT UNFORMATTED cLine nuskaito lygiai vieną eilutę. ‍
  • IF cLine BEGINS cSentinel tikrina, ar tai žymės eilutė. Jei taip, SUBSTRING() paima skaičių po žymės, INTEGER() jį konvertuoja, o rezultatas įrašomas į piExitCode. NEXT praleidžia šią eilutę, todėl žymė niekada nepasiekia kviečiančiosios procedūros. ‍
  • pcOutput = pcOutput + cLine + CHR(10) visas kitas eilutes prideda prie išvesties. CHR(10) grąžina eilutės lūžį, kurį pašalina IMPORT UNFORMATTED. ‍
  • INPUT CLOSE uždaro srautą, o paskutinis patikrinimas iškelia ABL klaidą, jei išėjimo kodas nėra 0.

Verta atkreipti dėmesį į dvi detales:

  • FORMAT "x(10000)" riboja, kiek simbolių nuskaitoma vienoje eilutėje. Padidinkite šią reikšmę, jei tikitės ilgesnių eilučių. ‍
  • OE_SHELL_PATH skirtas tik testavimui ne Linux aplinkoje. Gamybinėje aplinkoje jo nenustatykite, kad procedūra naudotų /bin/sh.

Kaip iškviesti tarpinę procedūrą iš ABL?

Procedūra doBackup.p iškviečia runScript.p ir užregistruoja gautą išvestį, nesvarbu, ar scenarijus pavyko, ar ne. Jei išėjimo kodas nėra 0, ji taip pat užregistruoja klaidą ir ją iškelia.

‍

DEFINE VARIABLE iRC   AS INTEGER  NO-UNDO. 
DEFINE VARIABLE lcOut AS LONGCHAR NO-UNDO. 

RUN runScript.p (INPUT "./sampleScript.sh --mode nightly", OUTPUT iRC, OUTPUT lcOut).  

LOG-MANAGER:WRITE-MESSAGE(STRING(lcOut)). 

IF iRC NE 0 THEN 
DO: 
    LOG-MANAGER:WRITE-MESSAGE("Backup FAILED, exit code " + STRING(iRC)). 
    RETURN ERROR "Nightly backup failed — see log for captured output.". 
END. 

‍

Testą vykdžiau Git Bash aplinkoje. Pirmoje ekrano kopijoje matyti sėkmingas paleidimas:

Kad sukelčiau klaidą, prieš paleisdamas scenarijų pašalinau šaltinio katalogą:

Naudojant paprastą OS-COMMAND, abu paleidimai būtų atrodę vienodai, o klaida liktų nepastebėta.

Kaip tvarkyti didelius Progress OpenEdge žurnalų failus neapkraunant AVM?

Didelių žurnalų failų neįkelkite į ABL atmintį. Progress OpenEdge žurnalus rotuokite su logrotate ir copytruncate parinktimi, kad nereikėtų perkrauti brokerio, o filtruokite juos operacinės sistemos lygmeniu su awk. Tada ABL gauna tik tas kelias eilutes, kurių jai iš tiesų reikia.

Mažiems failams skaityti su INPUT FROM visiškai tinka. Tačiau kelių gigabaitų žurnalai gali išnaudoti visą atmintį ir sulėtinti kitaip sklandžiai veikiantį duomenų bazės brokerį.

Kodėl OpenEdge brokeriui reikia copytruncate?

Brokeris, t. y. duomenų bazės serverio procesas, laiko savo žurnalo failą atidarytą tol, kol veikia. Jei rotacijos metu įrankis failą pervadina ar ištrina, brokeris toliau rašo į senąjį failą, o naujos žurnalo eilutės nepastebimai dingsta.

logrotate parinktis copytruncate šios problemos išvengia. Ji nukopijuoja dabartinį turinį į naują failą, o originalų failą išvalo vietoje. Brokeris toliau rašo į tą patį failą be perkrovimo, ir nė viena žurnalo eilutė nedingsta. Progress tą pačią problemą aprašo straipsnyje How to truncate UBROKER log files while the Broker is running on UNIX, o Progress dokumentacijoje aprašyta, kaip archyvuoti ir trumpinti duomenų bazės žurnalus.

Kaip sukonfigūruoti logrotate OpenEdge žurnalams?

logrotate – tai nedidelė, dažniausiai iš anksto įdiegta Linux priemonė, kuri pervadina, suspaudžia ir šalina senus žurnalų failus. Ji turi taisykles įprastiems sistemos žurnalams, bet nieko nežino apie /var/log/openedge/. Todėl OpenEdge žurnalai auga tol, kol jiems nesukuriama konfigūracija:

‍

/var/log/openedge/broker.log 
/var/log/openedge/client*.log { 
    daily 
    rotate 14 
    maxsize 500M 
    compress 
    delaycompress 
    missingok 
    notifempty 
    copytruncate 
}

‍

Išsaugokite šį failą kaip /etc/logrotate.d/openedge. Jis nurodo logrotate rotuoti žurnalus kasdien arba anksčiau, jei jie viršija 500 MB, saugoti 14 senų kopijų ir naudoti copytruncate, kad brokerio darbas nebūtų sutrikdytas.

Dvi eilutės prieš { nurodo, kuriems failams taikomos taisyklės. /var/log/openedge/broker.log – tai vienas konkretus failas, o /var/log/openedge/client*.log atitinka client1.log, client2.log ir kitus panašius failus. Taisyklės tarp { } taikomos jiems visiems.

Kaip filtruoti žurnalo klaidas su awk iš ABL?

Procedūra extractLogErrors.p sudaro awk komandą, kuri filtruoja žurnalą pagal datą ir žodį ERROR, o tada paleidžia ją per tą pačią runScript.p procedūrą. Kviečiančioji procedūra visada gauna išėjimo kodą ir atitinkančias eilutes vienodu būdu, nepriklausomai nuo žurnalo failo ar datos.

‍

DEFINE INPUT PARAMETER pcLogFile    AS CHARACTER NO-UNDO. 
DEFINE INPUT PARAMETER pcFilterDate AS CHARACTER NO-UNDO. 
 
DEFINE VARIABLE iRC      AS INTEGER   NO-UNDO. 
DEFINE VARIABLE lcErrors AS LONGCHAR  NO-UNDO. 
DEFINE VARIABLE cAwkCmd  AS CHARACTER NO-UNDO. 
 
cAwkCmd = SUBSTITUTE("awk '/^&1/ &&&& /ERROR/ ~{ print ~}' &2", pcFilterDate, pcLogFile). 
 
RUN runScript.p 
    ( INPUT  cAwkCmd 
    , OUTPUT iRC 
    , OUTPUT lcErrors ). 
 
IF iRC NE 0 THEN 
    RETURN ERROR SUBSTITUTE("Log filtering failed (exit &1)", iRC). 
 
IF lcErrors = "" THEN 
    LOG-MANAGER:WRITE-MESSAGE(SUBSTITUTE("No ERROR entries found for &1 in &2", pcFilterDate, pcLogFile)). 
ELSE 
    LOG-MANAGER:WRITE-MESSAGE(SUBSTITUTE("ERROR entries for &1:~n&2", pcFilterDate, lcErrors)).

Štai kaip tai veikia:

  1. pcLogFile ir pcFilterDate nurodo, kurį žurnalo failą tikrinti ir pagal kurią datą filtruoti, pavyzdžiui, "2026-09-19". ‍
  2. cAwkCmd iš šablono sudaro awk komandą. ‍
  3. RUN runScript.p paleidžia komandą. Tarpinei procedūrai nesvarbu, ar ji vykdo awk, ar atsarginių kopijų scenarijų. Išėjimo kodą ji grąžina į iRC, o awk išvestį – į lcErrors.
  4. Jei iRC nėra 0, pavyzdžiui, dėl klaidingos sintaksės ar trūkstamo failo, procedūra iškelia klaidą. Tai tas pats greito sustojimo principas kaip doBackup.p.
  5. Tik tada tikrinamas lcErrors. Jei jis tuščias, awk tai datai nieko nerado, todėl užregistruojamas pranešimas „No ERROR entries found“. Priešingu atveju užregistruojamos rastos eilutės.

lcErrors yra bendrosios paskirties išvesties kintamasis, kaip lcOut procedūroje doBackup.p. Jame yra tik ERROR eilutės, nes būtent jas spausdina awk komanda. Rezultatai per LOG-MANAGER įrašomi į OpenEdge kliento žurnalą, todėl šaltinio žurnalo failas niekada nekeičiamas.

Dvi šablono dalys atrodo neįprastai dėl pačios ABL eilučių taisyklių:

  • ~{ ~} ekranuoja riestinius skliaustus. Be tildžių ABL preprocesorius { print } skaito kaip nuorodą į įtraukiamą failą. ‍
  • &&&& virsta &&. SUBSTITUTE() simbolį & laiko savo vietaženklio (&1, &2) pradžia, todėl awk operatorių && reikia rašyti dukart.

Kaip patikrinti žurnalo filtrą?

Filtrui patikrinti naudojau šį pavyzdinį žurnalą:

‍

2026-09-18 08:12:03 INFO Broker started, listening on port 5162 
2026-09-18 09:44:11 INFO Client session 1042 connected 
2026-09-18 14:02:57 ERROR Database connection pool exhausted, retrying 
2026-09-18 22:10:45 INFO Nightly batch job completed 
2026-09-19 00:01:02 INFO Broker health check OK 
2026-09-19 03:15:29 ERROR Disk usage on /db01 exceeded 90% threshold 
2026-09-19 07:30:10 INFO Client session 1043 connected 
2026-09-19 07:45:22 ERROR Timeout waiting for record lock on customer table 
2026-09-19 12:00:00 INFO Broker health check OK 
2026-09-19 18:20:38 ERROR Backup script exited with non-zero status

‍

Testas vykdomas procedūroje doLogCheck.p. Tai paprasta kviečiančioji procedūra, sukurta tuo pačiu principu kaip doBackup.p. Ji per SESSION:PARAMETER nuskaito datą, perduotą paleidimo parinktimi -param. Jei data neperduota, naudojama šiandienos data YYYY-MM-DD formatu. Šis formatas atitinka žurnalo laiko žymas, nes awk šablonas ieško datos kiekvienos eilutės pradžioje.

‍

DEFINE VARIABLE cDate AS CHARACTER NO-UNDO. 
 
cDate = SESSION:PARAMETER. 
IF cDate = ? OR cDate = "" THEN 
    cDate = STRING(YEAR(TODAY), "9999") + "-" + STRING(MONTH(TODAY), "99") + "-" + STRING(DAY(TODAY), "99"). 
 
RUN extractLogErrors.p (INPUT "sampleAppLog.log", INPUT cDate).

‍

Rezultatas atrodo taip:

Labai didelių failų, pavyzdžiui, dešimčių gigabaitų žurnalų, neapdorokite iš brokerio ar sesijos, aptarnaujančios aktyvius naudotojus. Paleiskite procesą kaip atskirą paketinę užduotį, kuri rezultatus įrašo ten, kur ABL galės juos vėliau perskaityti. Taip laukimas, kol awk baigs darbą, nestabdys nieko, kas matoma naudotojams.

Kaip įdiegti šį sprendimą Progress OpenEdge aplinkoje?

Sprendimą įdiegsite per šešis žingsnius: padarykite scenarijų vykdomą, iškvieskite jį keliu, kurį „shell“ randa, įdiekite ABL tarpinę procedūrą, įjunkite OpenEdge kliento žurnalą, įdiekite logrotate konfigūraciją bei patikrinkite ir sėkmingą, ir nesėkmingą scenarijų.

1. Padarykite scenarijų vykdomą ir kontroliuokite, kas jį gali paleisti.  

Paleiskite chmod +x sampleScript.sh, nes nevykdomas failas nepasileis. Apribokite teises taip, kad scenarijų tiesiogiai galėtų paleisti tik OpenEdge paskyra, o visi kiti naudotų ABL tarpinę procedūrą. Taip registruojami ir jų paleidimai.

2. Naudokite kelią, kurį „shell“ gali rasti.  

Vien failo pavadinimas, pavyzdžiui, sampleScript.sh, veikia tik tada, jei jo katalogas yra PATH kintamajame. Naudokite ./sampleScript.sh, jei failas tame pačiame kataloge, arba pilną kelią.

3. Paruoškite ABL dalį.  

runScript.p padėkite ten, iš kur ją gali iškviesti kiti .p failai, ir kvieskite ją taip pat, kaip tai daro doBackup.p ir extractLogErrors.p.

4. Įjunkite OpenEdge kliento žurnalą.  

Prieš kviesdami LOG-MANAGER:WRITE-MESSAGE, įjunkite žurnalą paleidimo parinktimi -clientlog arba kode nustatydami LOG-MANAGER:LOGFILE-NAME. Kitaip pranešimai neturės kur būti įrašyti.

5. Įdiekite logrotate konfigūraciją.  

Padėkite ją Linux serverio kataloge /etc/logrotate.d/. Prieš ja pasitikėdami, paleiskite logrotate -d /etc/logrotate.d/openedge. Parinktis -d parodo, kas įvyktų, nekeisdama jokių failų.

6. Patikrinkite abu rezultatus.  

Paleiskite užduotį, kai viskas veikia, o tada tyčia ją sugadinkite, pavyzdžiui, nukreipkite atsarginių kopijų scenarijų į neegzistuojantį katalogą. Įsitikinkite, kad išėjimo kodas ir klaidos tekstas atsiranda žurnale. Kol nematėte užfiksuotos klaidos, klaidų apdorojimas nėra patikrintas.

Su kokiais iššūkiais galite susidurti?

Dauguma problemų kyla dėl ABL eilučių apdorojimo, duomenų tipų apribojimų ir aplinkų skirtumų. Lentelėje pateikiamos testuojant pastebėtos problemos ir jų sprendimai.

‍

Iššūkis Priežastis Sprendimas
awk komanda nesikompiliuoja, rodoma klaida „print was not found (293)“ ABL preprocesorius { } skaito kaip nuorodą į įtraukiamą failą, net kabutėse Ekranuokite skliaustus: ~{ print ~}
awk nepavyksta vykdymo metu, nes && virsta & SUBSTITUTE() simbolį & naudoja savo vietaženkliams (&1–&9) Šablone rašykite &&&&
Klaida 11382 OpenEdge 12.8 versijoje LONGCHAR netinka IMPORT UNFORMATTED ir INPUT THROUGH VALUE() Eilutės ir komandos kintamiesiems naudokite CHARACTER, o LONGCHAR palikite tik sukauptai išvesčiai
„Command not found“ (išėjimo kodas 127) Vien scenarijaus pavadinimas priklauso nuo PATH. Tai lengva praleisti testuojant iš paties scenarijaus katalogo Naudokite ./ arba absoliutų kelią
Sprendimo negalima pilnai patikrinti Windows aplinkoje _progres.exe procesus paleidžia per Windows API, kuri neranda /bin/sh Patikrinkite tikrame Linux serveryje
awk rezultatai skiriasi skirtingose sistemose Sprendimas patikrintas su GNU awk (gawk) Prieš naudodami gamybinėje aplinkoje, patikrinkite reguliariųjų išraiškų veikimą su mawk ar BSD awk
logrotate -d negalima patikrinti ne Linux aplinkoje Reikia Linux serverio, o tikram paleidimui su sistemos žurnalų keliais dažniausiai reikia root teisių Konfigūraciją patikrinkite tiksliniame Linux serveryje

‍

Ką parodė testai?

Abu sprendimai veikė taip, kaip numatyta. „Shell“ o logika testuota Git Bash aplinkoje Windows sistemoje, o ne Linux serveryje. Git Bash turi tikrą POSIX „shell“ (/bin/sh, awk, chmod), todėl „shell“ ir awk logika veikia taip pat kaip Linux. ABL kodas vykdytas tikroje AVM.

  • Pirmasis atvejis: sėkmingas paleidimas grąžino iRC = 0 su visa išvestimi. Tyčia sukelta klaida grąžino iRC = 10 kartu su tikra tar klaidos eilute iš stderr. ‍
  • Antrasis atvejis: awk filtras iš sampleAppLog.log grąžino lygiai tris ERROR eilutes 2026-09-19 datai, o datai be atitikmenų teisingai negrąžino nieko. ‍
  • runScript.p: ištaisius LONGCHAR ir IMPORT UNFORMATTED problemas, procedūra tikroje AVM susikompiliavo ir veikė be klaidų. Tai patvirtina, kad išėjimo kodo gavimas veikia ABL lygmeniu, nesvarbu, kokią komandą vykdo tarpinė procedūra.

Svarbiausios įžvalgos apie „shell“ įrankių naudojimą Progress OpenEdge aplinkoje

„Shell“ kvietimas iš Progress OpenEdge nebūtinai reiškia matomumo praradimą. Paleidus scenarijus per INPUT THROUGH su sujungtu stderr ir žymės eilute, tylios klaidos virsta išėjimo kodais ir klaidų tekstu, kuriuos ABL gali patikrinti ir užregistruoti. Perkėlus žurnalų filtravimą į awk, o rotaciją į logrotate su copytruncate, dideli failai lieka už AVM atminties ribų, o brokeris veikia be pertraukų.

Šie sprendimai išsprendžia tris praktines problemas:

  • Tylios klaidos tampa matomos. ABL požiūriu OS-COMMAND visada atrodo sėkmingas. INPUT THROUGH su žymės eilute suteikia ABL tikrą išėjimo kodą ir klaidos tekstą. ‍
  • Žurnalo dydis nebėra ABL atminties problema. Filtruojama su awk už AVM ribų, o ABL gauna tik atitinkančias eilutes. ‍
  • Rotacijai nebereikia perkrauti brokerio. copytruncate išvalo žurnalo failą vietoje, todėl brokerio atidarytas failas išlieka galiojantis.

Jei planuojate padidinti savo Progress OpenEdge programų patikimumą arba jums reikia pagalbos tvarkant scenarijus ir žurnalus, mūsų Progress OpenEdge komanda pasiruošusi padėti. Užsiregistruokite konsultacijai su mūsų specialistais ir aptarkime jūsų sprendimą.

No items found.

Susiję straipsniai

Pasikalbėkime apie jūsų projektą

Pradedate projektą arba norite sustiprinti jau vykdomą? Susisiekite ir atsakysime jums per vieną darbo dieną.

Parašykite mums

Ačiū! Jūsų pateikimas gautas!
Oi! Pateikiant formą kažkas nutiko.