FAQ - Kostra skriptu pro Windows pro manipulaci s jednotkami

Sekce pro všeobecné rady a návody z oblasti DC projektů
Odpovědět
Zpráva
Autor
nenym
78.9473684211 %
78.9473684211 %
Příspěvky: 7610
Registrován: úte 13 led, 2009 15:33
rok narození: 0- 0-1956
ID CNT statistics: 10124

Re: Udělátko na rušení chybných jednotek

#1 Příspěvek od nenym »

Potřeboval bych návod, jak
- zobrazit výsledek get_tasks na monitoru (asi v okně cmd),
- vypreparovat, zda je na daném projektu vůbec nějaká jednotka natažená,
- vypreparovat, zda je v daném projektu (tedy patrně zpracovat výsledek get_tasks) nějaká jednotka ve stavu "running",
- udržet nesuspendutných x tasků daného projektu (to je skriptík NFS).
Patrně je to pořád o přežvýkání get_tasks, takže by mi mělo stačit zobrazení výsledku někde (monitor, soubor), abych mohl dále tvořit sám. No a nějaký aspoň drobný komentář k tvému scriptu pro FreeHal, ať pochopím, co jsi tam kouzlil, zkusím to uplácat sám.
Blíží se konsolidační balíček pětikolky; šetřím trojbojem - piji staré víno, jím plesnivé sýry a jezdím v autě bez střechy.
UotD 767x Obrázek
1xObrázek 3xObrázek 9xObrázek 12xObrázek Obrázek
Obrázek

Uživatelský avatar
vkliber
Admin webu a fóra CNT
Admin webu a fóra CNT
Příspěvky: 10306
Registrován: čtv 29 bře, 2007 10:41
ID CNT statistics: 1
Bydliště: Brušperk, 48 let
Kontaktovat uživatele:

FAQ - Kostra skriptu pro Windows pro manipulaci s jednotkami

#2 Příspěvek od vkliber »

Zakládám toto vlákno jako reakci na
nenym píše:Potřeboval bych návod, jak
- zobrazit výsledek get_tasks na monitoru (asi v okně cmd),
- vypreparovat, zda je na daném projektu vůbec nějaká jednotka natažená,
- vypreparovat, zda je v daném projektu (tedy patrně zpracovat výsledek get_tasks) nějaká jednotka ve stavu "running",
- udržet nesuspendutných x tasků daného projektu (to je skriptík NFS).
Patrně je to pořád o přežvýkání get_tasks, takže by mi mělo stačit zobrazení výsledku někde (monitor, soubor), abych mohl dále tvořit sám. No a nějaký aspoň drobný komentář k tvému scriptu pro FreeHal, ať pochopím, co jsi tam kouzlil, zkusím to uplácat sám.
Vyšel jsem ze skriptu pro rušení jednotek projektu FreeHAL (zde) a vytvořil univerzální kostru skriptu pro Windows.
Opět je napsáno v JScriptu, honosný název boinc_framework.js 45cc .
Obsahuje zřejmě více komentářů než výkoného kódu, proto se to zdá na první pohled příšerně složité, ale ve skutečnosti to vlastně nic nedělá. Je popsáno uvnitř, ve stručnosti jen toto : na začátku deklarace nějakých proměných, deklarace funkcí a začíná to na řádku /* MAIN */ 45cc .
Opět platí : nutno umístit do stejného adresáře kde se nachází boinccmd.exe a z tohoto adresáře také spouštet, například v cmd (příkazové řádce). Můžete bez obav spustit, nic to nezpůsobí.

Skript po spuštění udělá přesně toto :
- spustí příkaz boinccmd.exe --get_tasks (nebo boinccmd.exe --get_results ... automaticky zjistí z verze)
- projde standardní výstup řádek po řádku
- pro projekt definovaný v proměné zjišťuje jednotky tohoto projektu
- tyto jednotky vypisuje na obrazovku

Předpokládám, že do této kostry pak dopíšu konkrétní akce na konkrétní požadavky, tak jak je to pro projekt NFS (zde)

Co se týká Jscriptu, tak na webu je hromada manuálů a příkladů (syntaxe : Jscript ~ JavaScript). Stránky přímo od MS jsou zde, ale tam se někam proklikat je pouze pro ty kteří ví přesně co chtějí (Learn > Reference > Windows Environment Development > Windows Shell > Shell Reference > Shell Objects for Scripting and Microsoft Visual Basic).
Lepší odkaz je zde.

Kód vypadá velice nepřehledně, doporučuji otevřít v editoru který rozpoznává syntaxi (používám PSPad), nebo přímo v nějakém Visual Studiu.

Kód: Vybrat vše

/*!
    Autor : Vit Kliber, Czech National Team o.s.
Vytvoreno : 10.01.2012
    Nazev : boinc_framework.js
    Popis : Kostra skriptu pro budouci skripy pro manipulaci s jednotkami
            Nutno umistit do stejneho adresare kde se nachazi boinccmd a z tohoto adresare take spoustet
*/

// verze boinc, je zjistena funkci verze(), pokud je prazdne nepodarilo se zjistit a skript se ukonci
var boinc_verze = "";

// prikaz pro zjisteni aktualnich jednotek v BOINC
var boinc_jednotky = "";

// prikaz pro manipulaci s jednotkou
var boinc_jednotka = "";

// adresa projektu (nejpravdepodobneji bude skript manipulovat s jednotkami jednoho projektu)
var projekt = "http://escatter11.fullerton.edu/nfs/";
//var projekt = "http://www.freehal.net/freehal_at_home/";

// 1 = Debug ON, 0 = Debug OFF ... jestli se maji vypisovat pri behu hlaseni
var debug_code = 1;

// pro vypsani ladiciho textu pri behu skriptu
function alert(text)
{
  if (debug_code != 0)
  {
    return (new ActiveXObject("WScript.Shell")).Popup(text, 0, WScript.ScriptName, 64);
  }
}

// zjisti verzi BOINC
function verze()
{
  // definice noveho objektu WScript.Shell (umozni mi spoustet externi prikazy)
  var objekt_shell = new ActiveXObject("WScript.Shell");
  // definice metody Exec, spusti prikaz a pointer uchova v promene <objekt_exec>
  var objekt_exec  = objekt_shell.Exec("boinccmd.exe --version");
  // textova promena do ktere se ulozi cely obsah standardniho vystupu predchazejiciho prikazu
  var verze_text   = objekt_exec.StdOut.ReadAll();
  alert(verze_text);
  // promena <verze_text> by mela nyni obsahovat jeden radek s timto obsahem (podle verze) : "boinccmd,  built from BOINC 6.12.33"
  // uchovam pozici textu BOINC z promene <verze_text>
  var pozice = verze_text.indexOf("BOINC");
  // jestlize je ruzne od -1 tak v obsahu <verze_text> je na pozici <pozice> text BOINC (podarilo se spustit prikaz "boinccmd.exe --version")
  if (pozice != -1)
  {
    // z <verze_text> vyriznu text od pozice <pozice> (prictu 6 ... delka textu BOINC a mezera)
    boinc_verze = verze_text.substr(6+pozice);
    // nyni je v <boinc_verze> hodnota 6.12.33
    alert(boinc_verze);
    return true;
  }
  else // verzi BOINC se nepodarilo zjistit, vracim FALSE
  {
    return false;
  }
}

// funkce pro porovnani dvou verzi ve tvaru X.X.X, ocekava promene ve tvaru pole
function porovnani_verzi(verze1, verze2)
{
  // promenne <verze1> a <verze2> jsou pole textovych retezcu, tak je prevedu na cisla
  verze1[0] = (parseInt(verze1[0]) || 0); 
  verze1[1] = (parseInt(verze1[1]) || 0); 
  verze1[2] = (parseInt(verze1[2]) || 0); 
  verze2[0] = (parseInt(verze2[0]) || 0); 
  verze2[1] = (parseInt(verze2[1]) || 0); 
  verze2[2] = (parseInt(verze2[2]) || 0); 
  if (verze2[0] != verze1[0])
    return (verze2[0] > verze1[0]);
  else
  {
    if (verze2[1] != verze1[1])
      return (verze2[1] > verze1[1]);
    else
    {
      if (verze2[2] != verze1[2])
        return (verze2[2] > verze1[2]);
      else
        return true;
    }
  }
}

// provede nastaveni promenych podle verze BOINC
function init()
{
  // od verze BOINC 6.12 vcetne je jina syntaxe programu boinccmd
  var verze_pro_porovnani = "6.12.0";
  // zavolam funkci ktera zjisti verzi BOINC a pokud se to podari nastavim zakladni promenne
  if (verze())
  {
    alert("Porovnavam verzi " + boinc_verze + " s referencni verzi " + verze_pro_porovnani);
    if (porovnani_verzi(verze_pro_porovnani.split('.'),boinc_verze.split('.')))
    {
      // Verze BOINC >= 6.12
      boinc_jednotky = "boinccmd.exe --get_tasks";
      boinc_jednotka = "boinccmd.exe --task";
    }
    else
    {
      // Verze BOINC <  6.12
      boinc_jednotky = "boinccmd.exe --get_results";
      boinc_jednotka = "boinccmd.exe --result";
    }
    return true;
  }
  else // funkce pro zjisteni verze se nepodarila, vracim FALSE
  {
    return false;
  }
}

/* MAIN */
// zavolam funkci ktera nastavi zakladni promenne
if (init())
{
  // v tuto chvili je uspesne zjistena verze a
  // uspesne nastavene zakladni promenne <boinc_jednotky> a <boinc_jednotka>
  // definuji novy objekt WScript.Shell (umozni mi spoustet externi prikazy)
  var objekt_shell = new ActiveXObject("WScript.Shell");
  // definuji metodu Exec, spusti prikaz <boinc_jednotky> a pointer uchova v promene <objekt_exec>
  var objekt_exec  = objekt_shell.Exec(boinc_jednotky);
  // textova promena do ktere se ulozi cely obsah standardniho vystupu predchazejiciho prikazu
  var text_vystup  = objekt_exec.StdOut.ReadAll();
  // na konec <text_vystup> jeste pridam jednu prazdnou sekci abych pak nemusel resit konec  
  text_vystup = text_vystup + '\n' + "X) -----------" + '\n';
  // promena <text_vystup> by mela nyni obsahovat cely standardni vystup ktery vraci prikaz "boinccmd.exe --get_tasks"
  // definuji pole do ktereho prevedu obsah <text_vystup>
  var pole_vystup  = new Array();
  // oddelovacem bude znak EOL (EndOfLine) neboli \n
  // pole <pole_vystup> se naplni tak, ze kazdy dalsi radek bude v dalsim prvku
  // 1. radek v  pole_vystup[0], 2. radek v  pole_vystup[1], ...
  pole_vystup = text_vystup.split('\n');
  // nyni musime v cyklu projit vsechny radky (vyzaduje znalost vystupu "boinccmd.exe --get_tasks")
  // jednotlive jednotky jsou oddeleny v sekcich a o kterou jednotku se jedna zjistime az uvnitr sekce
  // takze si do nejakych promenych musime ukladat co budeme dale potrebovat a az sekce skonci
  // (zacne nova ... proto jsme si na konec pridali jednu prazdnou sekci pro ukonceni posledni sekce)
  // tak se rozhodneme podle obsahu ulozenych promenych co dal podnikneme
  // pripravim si promenne
  var b_name            = ""; // nazev jednotky (name)
  var b_state           = ""; // stav jednotky (state)
  var b_scheduler_state = ""; // stav scheduleru jednotky (scheduler state)
  var ano               = 0;  // 1 = ANO, 0 = NE ... jestli se jedna o projekt ktery nas zajima
  // a ted cyklus pres cele pole
  for(var i = 0; i < pole_vystup.length; i++)
  {
    // jestlize radek obsahuje text ") -----------" tak se jedna o zacatek nove sekce
    if (pole_vystup[i].indexOf(") -----------") != -1)
    {
      // jestlize je <ano> nastaveno (jedna se o projekt ktery nas zajima) je treba provest pozadovanou akci
      if (ano == 1) {
        alert("Projekt:" + projekt + "\nJednotka:" + b_name + "\nStav:" + b_state + "\nStav scheduleru:" + b_scheduler_state);
/*
Zde bude vykony kod ktery bude neco provadet s konkretnimi jednotkami.
Vyhodnotime obsah promenych :
<b_name> ... nazev jednotky ... zrejme budeme jeste zjistovat jestli nazev odpovida nejakemu textu, napr. jestli obsahuje text GPU
<b_state> ... stav jednotky ... zrejme nas bude zajimat v jakem stavu jednotka je (je treba zjistit co ktery stav znamena)
<b_scheduler_state> ... stav scheduleru jednotky ... zrejme nas bude zajimat v jakem stavu je (je treba zjistit co ktery stav znamena)
   ... asi bude nutne pridat dalsi promene podle obsahu vystupu "boinccmd.exe --get_tasks"
   ... bude nas urcite zajimat jestli je jednotka ve stavu suspend nebo resume
   ... bude treba projit dokumentaci (nebo zdrojaky) pro "boinccmd.exe" a zjistit presne co ktera hodnota znamena
V pripade ze se bude jednat o nejakou akci s jednotkou ktera neni zavisla na ostatnich jednotkach,
muzeme akci provest primo.
---
Napriklad pro verzi kde bude pozadovano ruseni jednotek jak je tomu pro
projekt FreeHAL ( http://forum.czechnationalteam.cz/viewtopic.php?p=53372#p53372 )
muzeme pozadovanou akci primo vykonat
        var abort_exec = objekt_shell.Exec(boinc_jednotka + " " + projekt + " " + b_name + " abort");
---
Naproti tomu pro verzi kde bude akce zaviset i na ostatnich jednotkach jak je tomu pro
projekt NFS ( http://forum.czechnationalteam.cz/viewtopic.php?p=37473#p37473 )
budeme muset jednotlive promenne uchovavat do nejakeho pole a pozadovane akce provest az skript vyskoci z tohoto cyklu
*/
      }
      // a po akci si opet vynulujeme promenne
      b_name = "";
      b_state = "";
      b_scheduler_state = "";
      ano    = 0;
    }
    // jestlize radek obsahuje text "   name: " tak se jedna o radek kde je nazev jednotky
    else if (pole_vystup[i].indexOf("   name: ") != -1)
    {
      // a nazev jednotky si uchovam do <b_name>
      b_name = pole_vystup[i].substr(9);
    }
    // jestlize radek obsahuje text "   state: " tak se jedna o radek kde je stav jednotky
    else if (pole_vystup[i].indexOf("   state: ") != -1)
    {
      // a stav jednotky si uchovam do <b_state>
      b_state = pole_vystup[i].substr(10);
    }
    // jestlize radek obsahuje text "   scheduler state: " tak se jedna o radek kde je stav scheduleru jednotky
    else if (pole_vystup[i].indexOf("   scheduler state: ") != -1)
    {
      // a stav scheduleru jednotky si uchovam do <b_scheduler_state>
      b_scheduler_state = pole_vystup[i].substr(20);
    }
    // jestlize radek obsahuje text "   project URL: " tak se jedna o radek kde je adresa projektu
    else if (pole_vystup[i].indexOf("   project URL: ") != -1)
    {
      // a jestli radek obsahuje i adresu projektu ktery me zajima, tak si nastavim <ano>
      if (pole_vystup[i].indexOf("   project URL: " + projekt) != -1)
      {
        ano = 1;
      }
      else
      {
        ano = 0;
      }
    }
  }
  // v pripade ze manipulace s jednotkami nebude provadena v predchazejicim cyklu,
  // ale pouze se ukladaly hodnoty do nejakeho pole,
  // tak tady budou nasledovat dalsi akce na zaklade hodnot v poli
  // ale to az priste :-)
}
alert("Konec.");
Statistiky CNT | Projekty CNT | Distribuované výpočty CNT | SETI CNT | Einstein CNT
.....::::: Proč se mít nejlépe, když se můžu mít čím dál tím stejně :::::.....
Moje skromná statistika tady , tady , tady nebo grafy.
˙ıɔıqɐɹʞ ʌ ǝןɐ 'ıןʇʎd ʌ ǝɔıɾɐz ǝʇɾndnʞǝu ʎpʞıu ˙˙˙

Uživatelský avatar
vkliber
Admin webu a fóra CNT
Admin webu a fóra CNT
Příspěvky: 10306
Registrován: čtv 29 bře, 2007 10:41
ID CNT statistics: 1
Bydliště: Brušperk, 48 let
Kontaktovat uživatele:

Re: FAQ - Kostra skriptu pro Windows pro manipulaci s jednot

#3 Příspěvek od vkliber »

Hmmm, akorát nemůžu nikde na webu berkeley.edu najít popis výstupu "boinccmd.exe --get_tasks" :smt102 .
Statistiky CNT | Projekty CNT | Distribuované výpočty CNT | SETI CNT | Einstein CNT
.....::::: Proč se mít nejlépe, když se můžu mít čím dál tím stejně :::::.....
Moje skromná statistika tady , tady , tady nebo grafy.
˙ıɔıqɐɹʞ ʌ ǝןɐ 'ıןʇʎd ʌ ǝɔıɾɐz ǝʇɾndnʞǝu ʎpʞıu ˙˙˙

Odpovědět

Zpět na „Rady a návody“