Download Game! Currently 92 players and visitors. Last logged in:GrizztSharTigerlilyPazi

Blitzer's Blog >> 71725

Back to blogs index
Posted: 12 Aug 2026 09:50 [ permalink ]
Mesh OS v0.1 - Ydin ladattu. VFS kytketty.
Kokeile komentoja: ls, mkdir testi, echo "hello" >&2
mesh@local:~$ echo "Tervetuloa, $USER. Kotikansiosi on $HOME"
Tervetuloa, mesh. Kotikansiosi on /home/mesh
mesh@local:~$ env
PATH=/bin:/usr/local/bin
USER=mesh
HOME=/home/mesh
PWD=/
mesh@local:~$ export PATH=$PATH:/mnt/ghost_proxy/bin
mesh@local:~$ echo $PATH
mesh@local:~$ echo '$USER on $USER, mutta " tC$C$llC$ se laajenee: $USER "'
$USER on $USER, mutta " tC$C$llC$ se laajenee: $USER "
mesh@local:~$ echo '$USER on $USER, mutta' "tC$C$llC$ se laajenee: $USER "
$USER on $USER, mutta tC$C$llC$ se laajenee: meshB
mesh@local:~$

==

import { IORouter } from './io.js';
import { parseIntent } from './parser.js';
import { C } from './cmd.js';

export function parsePipeline(str, env) {
    return str.split('|').map(x => parseIntent(x, env)).filter(x => x !==
null);
}

export class ShellSession {
    constructor(sessionId) {
        this.id = sessionId;
        this.io = new IORouter();
        this.history = []; 
        
        // UUSI: UNIX-ympC$ristC6muuttujat oletuksina!
        this.env = {
            PATH: "/bin:/usr/local/bin",
            USER: "mesh",
            HOME: "/home/mesh",
            PWD: "/"
        };

        this.io.open(0); 
        this.io.open(1, (data) => this._defaultOut(data)); 
        this.io.open(2, (data) => this._defaultErr(data)); 
    }

    _defaultOut(msg) { console.log(msg); }
    _defaultErr(msg) { console.error(msg); }

    async executeRaw(inputString) {
        // VC$litetC$C$n env parserille laajennusta varten
        const pipeline = parsePipeline(inputString, this.env);
        if (!pipeline.length) return;
        
        let previousOutput = null;

        for (let i = 0; i < pipeline.length; i++) {
            const intent = pipeline[i];
            this.history.push(intent);
            
            for (const r of intent.redirects) this.io.tee(r.source, r.target);

            let cmdKey = intent.cmd;
            if (typeof C[cmdKey] === 'string') cmdKey = C[cmdKey];
            const cmdFn = C[cmdKey];

            if (cmdFn) {
                let currentOutput = [];
                const isLast = (i === pipeline.length - 1);
                const w = (d) => { (intent.fileOut || !isLast) ?
currentOutput.push(d) : this.io.write(1, d); };
                const e = (d) => this.io.write(2, d);
                
                try {
                    // LisC$tC$C$n kuudes parametri: env
                    await cmdFn(intent.argv, w, e, window.fs, previousOutput,
this.env);
                    let outStr = currentOutput.join('
');
                    
                    if (intent.fileOut) {
                        const f = intent.fileOut.file;
                        let old = intent.fileOut.append ? await
window.fs.readFile(f).catch(()=>"") : "";
                        await window.fs.writeFile(f, old ? old + "
" + outStr : outStr);
                        previousOutput = ""; 
                    } else previousOutput = outStr;
                } catch (err) {
                    e("Fatal: " + err.message); break;
                }
            } else {
                // UNIX PATH -lokigikka (placeholder tulevia VFS-skriptejC$
varten)
                const paths = this.env.PATH.split(':');
                this.io.write(2, `bash: ${intent.cmd}: command not found
(searched in ${paths.length} directories)`);
                break;
            }

            for (const r of intent.redirects) this.io.untee(r.source,
r.target);
        }
    }
}

==

/ a: argv, w: stdout, e: stderr, v: vfs, i: stdin, n: env
export const C = {
    echo: (a,w,e,v,i,n) => w(a.join(' ')),
    cat: async(a,w,e,v,i,n) => a.length ? w(await v.readFile(a[0]).catch(x=>e(x
.message))) : w(i||""),
    ls: async(a,w,e,v,i,n) => w((await v.readdir(a[0]||'/')).join('
')),
    mkdir: async(a,w,e,v,i,n) => v.mkdir(a[0]).then(()=>w('ok')).catch(x=>e(x.m
essage)),
    rm: async(a,w,e,v,i,n) => v.unlink(a[0]).then(()=>w('ok')).catch(x=>e(x.mes
sage)),
    grep: (a,w,e,v,i,n) => {
        if (!i) return;
        const result = i.split('
').filter(line => line.includes(a[0]));
        if (result.length) w(result.join('
'));
    },
    tee: async(a,w,e,v,i="",n) => { w(i); for(let f of a) await v.writeFile(f,
i); },
    
    // UUDET: YmpC$ristC6muuttujien hallinta
    env: (a,w,e,v,i,n) => w(Object.entries(n).map(([k,val])=>`${k}=${val}`).joi
n('
')),
    export: (a,w,e,v,i,n) => {
        if (!a.length) return w(Object.entries(n).map(([k,val])=>`declare -x
${k}="${val}"`).join('
'));
        let [k, ...val] = a[0].split('=');
        if(k) n[k] = val.join('=');
    },

    ll: "ls", md: "mkdir"
};