Negli ultimi tempi termini come LLM, embedding e database vettoriali sono usciti rapidamente dall’ambito della ricerca e sono diventati argomenti quasi quotidiani. sono mattoni nocoi quai possiamo costruire sistemi capaci di interrogare grandi collezioni di …
Ho condotto un esperimento di scrittura di software per analizzare i risultati di una esportazione delle mie conversazioni con ChatGPT. Ma ho deciso di aiutarmi nell’analisi con un Large Language Model che sicuramente sa fare molto bene questo lavoro e in più con un LLM in locale, per vedere come funziona.
Negli ultimi giorni ho avuto problemi intermittenti con un mouse Bluetooth Trust (modello 24059-02) connesso al mio HP con Ubuntu. Il mouse ha funzionato regolarmente per un paio di giorni, poi improvvisamente ha smesso di …
Ho installato la versione 24.3.1.347 di Oracle SQL Developer però ho una sorpresa: sembra non sia possibile raggruppare le connessioni in cartelle. Risposta: Eh sì — è una sorpresa che ha colpito parecchi utenti anche …
Quando si esegue uno script Bash ci sono due modalità principali da impiegare, che hanno conseguenze diverse sull’ambiente della shell. 1. Esecuzione diretta (./script.sh) Quindi può solo leggere le variabili di ambiente della shell madre …
Negli ultimi tempi termini come LLM, embedding e database vettoriali sono usciti rapidamente dall’ambito della ricerca e sono diventati argomenti quasi quotidiani. sono mattoni nocoi quai possiamo costruire sistemi capaci di interrogare grandi collezioni di documenti non più tramite ricerca lessicale tradizionale, ma attraverso la vicinanza semantica tra i testi.
In questi giorni ho realizzato un piccolo prototipo sperimentale di sistema RAG (Retrieval-Augmented Generation) utilizzando esclusivamente strumenti locali: PostgreSQL con l’estensione pgvector, Ollama, Python e una macchina Linux piuttosto modesta, un Intel i5 con 16 GB di RAM e senza alcuna GPU CUDA.
L’obiettivo era capire davvero cosa succede dentro queste architetture che oggi vengono spesso presentate in modo un po’ magico.
Il funzionamento generale è relativamente semplice. I documenti PDF vengono letti, suddivisi in piccoli frammenti e trasformati in embedding numerici tramite un modello locale. Questi vettori vengono memorizzati in PostgreSQL. Quando l’utente pone una domanda, anche la domanda viene convertita in un embedding e il database cerca i frammenti semanticamente più vicini. Solo a quel punto il modello linguistico riceve il contesto recuperato e prova a costruire una risposta.
La parte interessante è che il database non cerca parole identiche come farebbe un classico LIKE, ma effettua una ricerca geometrica nello spazio degli embedding. In altre parole, il sistema tenta di individuare testi “concettualmente vicini” alla domanda.
La sorpresa più grande dell’esperimento è stata probabilmente PostgreSQL. Anche con oltre sedicimila chunk indicizzati, le interrogazioni vettoriali risultavano rapidissime, dell’ordine di pochi decimi di secondo. Il vero collo di bottiglia si è invece manifestato nella generazione finale della risposta da parte del modello linguistico locale.
Qui si entra nel territorio dell’algebra lineare pesante: matrici enormi, meccanismi di attenzione, inferenza autoregressiva token per token. Su CPU tutto questo funziona, ma i tempi crescono rapidamente. In alcuni casi Ollama arrivava addirittura in timeout durante la generazione della risposta.
È stato quindi necessario introdurre varie ottimizzazioni: ridurre il numero di chunk passati al modello, limitare la lunghezza dell’output e rendere più robusta la gestione degli errori. Anche così, le risposte ottenute rimangono talvolta “maccheroniche” o affette da piccole allucinazioni semantiche, ma nel complesso la direzione sembra corretta, soprattutto considerando il setup estremamente limitato.
L’aspetto più istruttivo dell’esperimento è forse proprio questo: osservare concretamente dove finisca il retrieval e dove inizi la generazione linguistica. Un sistema RAG non è semplicemente “un chatbot collegato a un database”, ma una pipeline piuttosto delicata in cui chunking, retrieval, ranking e costruzione del prompt influenzano pesantemente il risultato finale.
Da qualche tempo mi chiedo: cosa ho davvero chiesto a ChatGPT in questi anni? Ho scaricato l’archivio completo delle mie conversazioni e ho deciso di analizzarlo — non con un servizio cloud, ma con un LLM in esecuzione sul mio PC. Questo post racconta l’esperimento, le scelte tecniche, i risultati e le riflessioni che ne sono emerse.
LLM per analizzare le mie chat con OpenAI
Perché Ollama, e perché in locale
La scelta di usare Ollama come runtime per il modello non è stata casuale. Ollama è un progetto open source scritto in Go che espone un server HTTP locale (sulla porta 11434) attraverso il quale è possibile interagire con modelli LLM esattamente come si farebbe con le API di OpenAI o Anthropic — ma senza inviare dati all’esterno e senza costi per token.
L’installazione su Linux è banale:
curl -fsSL https://ollama.com/install.sh | sh
ollama pull phi3:mini
ollama serve
Da quel momento, il modello è raggiungibile via HTTP esattamente come un’API cloud:
POST http://localhost:11434/api/generate
{
"model": "phi3:mini",
"prompt": "...",
"stream": false
}
Ovviamente il prompt può essere anche scritto da linea di comando, come si farebbe con un chatbot normale, ma in questo caso il prompt viene inoltrato al motore LLM da uno script Python che ripete tante volte lo stesso prompt con parametri diversi.
Questo è il cuore del paradigma: scrivi codice per la struttura, delega al LLM tutto ciò che richiede comprensione del linguaggio naturale.
La scelta del modello: phi3:mini e i vincoli hardware
Il mio PC è un HP Laptop 15s con CPU Intel i5 a 12 core e alimentatore da 45W — nessuno slot PCIe, nessuna possibilità di aggiungere una GPU dedicata. L’intera elaborazione avviene su CPU.
In questo contesto, phi3:mini di Microsoft è stata la scelta obbligata ma non scontata. Si tratta di un modello da 3.8 miliardi di parametri, ottimizzato per ragionamento e instruction following, con un peso di circa 2.2 GB in VRAM (o RAM, nel mio caso). Le alternative come LLaMA 3 8B o Mistral 7B avrebbero richiesto il doppio della memoria e tempi di inferenza ancora più lunghi.
Il log di Ollama durante il caricamento mostra chiaramente il contesto di esecuzione:
llama_kv_cache: CPU KV buffer size = 1536.00 MiB
llama_context: Flash Attention was auto, set to enabled
llama_runner started in 2.30 seconds
Il warning n_ctx_seq (4096) < n_ctx_train (131072) indica che il modello è stato addestrato per gestire contesti fino a 131k token, ma Ollama lo esegue con una finestra di 4096 — più che sufficiente per i nostri prompt.
Il formato dei dati: l’export di ChatGPT
ChatGPT permette di scaricare l’intero archivio delle conversazioni in formato JSON. La struttura non è banale: ogni conversazione è rappresentata come un grafo di nodi collegati da relazioni parent/child, non come una semplice lista di messaggi.
Il campo create_time è un Unix timestamp — i secondi trascorsi dal 1° gennaio 1970 (Unix Epoch). Per ricostruire la conversazione in ordine cronologico è necessario risalire la catena dei nodi a partire da current_node fino alla radice, poi invertire il percorso.
L’architettura dello script
Lo script Python è organizzato in tre livelli funzionali:
Estrazione: legge i file JSON, ricostruisce la catena di messaggi da ogni conversazione
Classificazione: per ogni conversazione costruisce un prompt e lo invia a Ollama via HTTP
Checkpoint: salva i progressi dopo ogni classificazione, permettendo di riprendere in caso di interruzione
Il punto cruciale è la generazione del prompt:
prompt = f"""Analizza questo frammento di conversazione e rispondi SOLO
con un oggetto JSON con questi campi:
- "argomento": una stringa breve (3-6 parole)
- "parole_chiave": una lista di 3-5 parole chiave
Conversazione:
{estratto}
Rispondi SOLO con il JSON, senza testo aggiuntivo."""
Cambiare questo prompt è tutto ciò che serve per trasformare lo script in un analizzatore di sentiment, un estrattore di entità, un sistema di moderazione. Il codice è la struttura, il prompt è la logica.
Questo è uno dei miei primi esperimenti di interazione tra software e LLM. Mi sono fatto aiutare da Anthropic – Claude nella stesura del codice, che però ho modificato e modulato a mio piacemento, ad esempio abbiamo aggiunto il meccaismo di checkpoint solo successivamente, dopo che ho visto che si doveva ripetere l’analisi dei prompt GPT da capo ogni volta che accadeva un errore o che femavo lo script per altri motivi. Così ho ottimizzato il tempo.
Ovviamente lasciar fare tutto ad un chatbot sarbbe stato più veloce ma così mi sari perso la parte divertente.
I risultati: 50 conversazioni analizzate
Ho analizzato un campione di 50 conversazioni estratte da un archivio di 1812. I numeri sono istruttivi.
Statistiche di elaborazione
Metrica
Valore
Conversazioni analizzate
50
Tempo totale
1471s (24,5 minuti)
Tempo medio per conversazione
42,0s
Tempo minimo
11,1s
Tempo massimo
258,7s
Distribuzione dei tempi
Fascia
Conversazioni
Meno di 20s
12 (24%)
20–40s
19 (38%)
40–60s
15 (30%)
Oltre 60s
4 (8%)
La variabilità è significativa: una conversazione breve richiede 11 secondi, una lunga o complessa può arrivare a quasi 4 minuti. Il collo di bottiglia è la generazione dei token su CPU — ogni token prodotto richiede un forward pass completo sulla rete neurale.
Qualità delle classificazioni
74% delle classificazioni sono pulite e corrette (37/50)
26% contengono JSON grezzo non parsato (13/50) — phi3:mini non ha sempre rispettato l’istruzione di rispondere solo con JSON
Questo è un problema noto nel prompt engineering: i modelli piccoli tendono a “ragionare ad alta voce” aggiungendo testo prima o dopo il JSON richiesto, rompendo il parsing. Le soluzioni possibili includono few-shot examples nel prompt, output structuring, o modelli più grandi.
Gli argomenti emersi
La distribuzione tematica delle mie conversazioni con ChatGPT rispecchia abbastanza fedelmente i miei interessi:
Fisica teorica: meccanica quantistica, Lagrangiana del Modello Standard, dilatazione del tempo, invarianti adiabatici, polarizzazione ottica
Programmazione: Python, JavaScript, PHP, Oracle SQL, Laravel, XML parsing, SQL injection, exploit di servizi remoti
Astronomia: coordinate celesti, sonde solari, visibilità dei poli lunari
Linux e IT: identificazione hardware, gestione della batteria, VPN
Storia della scienza: Galileo e il Copernicanesimo
Varie: tossicità delle piante per i gatti, lavatrice Samsung, il fiume Sile
Riflessioni e sviluppi futuri
Questo esperimento ha confermato qualcosa di importante: usare un LLM come componente di un programma è sorprendentemente accessibile. Non serve GPU, non servono librerie complesse, non serve conoscere i dettagli interni del modello. Basta una chiamata HTTP e un prompt ben formulato.
Il vero cambio di paradigma è concettuale: invece di scrivere codice per ogni singola regola di classificazione, si scrive codice per la struttura del problema e si delega la comprensione del linguaggio naturale al modello. Questo apre possibilità enormi — analisi di email, estrazione di dati da documenti non strutturati, moderazione di contenuti, generazione di dati di test — con una quantità di codice sorprendentemente piccola.
I limiti emersi sono altrettanto istruttivi:
Velocità su CPU: 42 secondi per conversazione rendono l’analisi dell’intero archivio (1812 conversazioni) un’operazione da 21 ore. Una GPU entry-level ridurrebbe questo tempo di un fattore 10-20x.
Affidabilità del formato di output: phi3:mini non rispetta sempre le istruzioni di formato. Modelli più grandi o tecniche di structured output migliorerebbero il 74% di successo.
Qualità semantica: le classificazioni corrette sono generalmente buone, ma alcuni argomenti sono descritti in modo troppo specifico per essere utili in un raggruppamento tematico.
I prossimi passi naturali sono estendere l’analisi all’intero archivio (magari con una GPU), aggiungere una modalità di ricerca semantica, e sperimentare con modelli più capaci come LLaMA 3 8B o Mistral 7B quando l’hardware lo permetterà.
Avere un LLM direttamente sulla macchina mi aprirà inoltre la possibilità di guardare sotto il cofano: capire come funzionano gli embeddings e la tokenizzazione, come viene applicato il softmax, come il modello costruisce la risposta token per token. Cose che si possono leggere sui paper, ma che diventano molto più concrete quando il modello gira davanti al tuo naso. È anche un modo per creare un primo mattoncino per la realizzazione di un vero e proprio Agente.
Trust Puck Bluetooth Mouse (codice 24059-02)Trust Puck Bluetooth Mouse (codice 24059-02)Trust Puck Bluetooth Mouse (codice 24059-02)
Negli ultimi giorni ho avuto problemi intermittenti con un mouse Bluetooth Trust (modello 24059-02) connesso al mio HP con Ubuntu. Il mouse ha funzionato regolarmente per un paio di giorni, poi improvvisamente ha smesso di connettersi, pur comparendo tra i dispositivi già accoppiati.
Questo è il resoconto del problema e della soluzione adottata, nella speranza che possa essere utile anche ad altri.
Il contesto hardware e software
Sistema operativo: Ubuntu 24.04 LTS
Scheda wireless integrata: Realtek RTL8821CE (Wi-Fi + Bluetooth combo)
Mouse: Trust Puck Bluetooth Mouse (codice 24059-02)
Dopo qualche tempo di funzionamento corretto, il mouse ha smesso di connettersi. L’indagine non è banale. A volte premere il pulsantino rosso sul retro – fino a che si vede una sequenza di led blu che scorre – è sufficiente per riattivare il mouse ma a volte non c’è nulla da fare: neppure spegnedo e riaccendendo il mouse, né staccando e ricollegando l’antennina.
Inizialmente mi sono chiesto se l’antenna fosse solo Wi-Fi o anche Bluetooth. Il chip Realtek RTL8821CE integra entrambi i protocolli e utilizza una sola antenna condivisa. Questo è tipico dei moduli combo wireless presenti nei portatili moderni: lo stesso circuito RF gestisce sia la trasmissione dati Wi-Fi che il canale BLE del mouse Bluetooth.
In questi moduli combo, l’alternanza tra Wi-Fi e Bluetooth avviene tramite una tecnica chiamata Time Division Multiplexing (TDM) per condividere il front-end RF, in modo da evitare interferenze interne.
Qui ho chiesto all’oracolo di San Gpt per ottenere lumi sulla questione. In breve la soluzione è il controller del Blutooth, bluetoothctl
Bluetoothctl
bluetoothctl è un tool da riga di comando per gestire dispositivi Bluetooth in ambiente Linux. Permette di accoppiare, connettere, scollegare e monitorare dispositivi direttamente dal terminale. È un client testuale che interagisce con il demone bluetoothd tramite il sistema D-Bus. Fa parte del pacchetto bluez, lo stack ufficiale per la gestione del Bluetooth su Linux. In pratica, è il comando testuale che consente di “parlare” direttamente con il sistema Bluetooth. Anche se spartano, è spesso più affidabile delle interfacce grafiche, specialmente quando i dispositivi fanno i capricci.
Un altro problema è stato reperire l’indirizzo MAC del device, ma ci si può arrivare facilemnte utilizzando i comandi sopra (lscpi o lsusb).
Al comando bluetoothctl connect <MAC> ricevevo messaggi come:
Failed to connect: org.bluez.Error.Failed Operation already in progress
Failed to connect: org.bluez.Error.Failed le-connection-abort-by-local
Nei log del kernel:
Bluetooth: hci0: unexpected cc 0x0c7c length: 1 < 3
bluetoothd[1152]: profiles/battery/battery.c:parse_battery_level() Trying to update an unregistered battery
Questi errori sono noti nel contesto dei dispositivi Bluetooth LE con chip Realtek. Il modulo rtw_8821ce presenta instabilità nella gestione della modalità a basso consumo (LPS) e problemi nel completare la connessione GATT con alcuni dispositivi.
La causa
Il mouse si accoppia correttamente ma, per motivi legati al driver o al timing del demone bluetoothd, la connessione BLE può venire interrotta dal sistema locale (errore le-connection-abort-by-local) oppure avviata quando i servizi del dispositivo non sono ancora completamente esposti. Ne consegue il mancato completamento della fase ServicesResolved.
La scheda Realtek è notoriamente sensibile a questi problemi, specialmente dopo resume da sospensione o dopo un pairing precedente lasciato in stato incoerente.
Soluzione adottata
Per ristabilire una connessione pulita al mouse, ho scritto uno script mouse_connect.sh da lanciare ogni volta che il mouse “si pianta”.
Il contenuto dello script
#!/bin/bash
# MAC del mouse Trust
MOUSE_MAC="CB:4C:45:8F:97:4C"
echo "Tentativo di riconnessione al mouse Trust ($MOUSE_MAC)..."
if ! systemctl is-active --quiet bluetooth.service; then
echo "Il servizio bluetooth non è attivo. Lo riavvio..."
sudo systemctl restart bluetooth.service
sleep 2
fi
bluetoothctl <<EOF
power on
agent on
default-agent
trust $MOUSE_MAC
connect $MOUSE_MAC
EOF
echo "Comando inviato. Verifica se il mouse si è riconnesso."
Lo script va salvato nella home directory e reso eseguibile con:
chmod +x ~/mouse_connect.sh
Può poi essere lanciato con:
./mouse_connect.sh
oppure si può creare un alias nel .bashrc:
alias reconn-mouse="~/mouse_connect.sh"
Considerazioni finali
Questo approccio ha permesso di aggirare il problema senza dover reinstallare driver o riavviare il sistema. Tuttavia, se il problema si ripresentasse con regolarità dopo ogni riavvio o sospensione, prenderò in considerazione:
Ho installato la versione 24.3.1.347 di Oracle SQL Developer però ho una sorpresa: sembra non sia possibile raggruppare le connessioni in cartelle.
Risposta:
Eh sì — è una sorpresa che ha colpito parecchi utenti anche esperti di SQL Developer! Vediamo bene la situazione
1. In SQL Developer 24.3.1 (e in generale 23.x–24.x)
Purtroppo l’interfaccia “Connections” non permette ancora di creare cartelle o gruppi gerarchici di connessioni, almeno non nel senso di folder drag-and-drop come molti si aspettano.
Puoi ordinare le connessioni alfabeticamente o rinominarle, ma non metterle in sotto-cartelle.
Poi ChatGPT mi elenca alcuni workaround:
usare prefissi nel nome
esportare e mantenere le connessioni dei vari gruppi in file separati
usare workspaces diversi
Conclude con:
3. Nota di roadmap
Oracle ha annunciato che la funzionalità di “Connection Folders” è prevista per una futura major release, ma non è ancora stata inclusa fino alla 24.3.1 (autunno 2025). Quindi per ora i prefix-based groups restano la soluzione più pratica.
Aggiorno il prompt
In realtà il mio collega mi ha fatto vedere come si fa, è posibile creare cartelle
Risposta (senza vergogna)
Esatto — ottimo colpo d’occhio del tuo collega! Hai ragione: nelle versioni recenti di SQL Developer (a partire dalla 23.1 in poi) Oracle ha finalmente reintrodotto la possibilità di creare cartelle di connessioni, ma la funzione è un po’ “nascosta”, quindi molti non la notano al primo sguardo.
In effetti la vergogna è un sentimento umano e le reti neurali non sanno cosa sia.
Attenzione: WordPress da problemi se includiamo nel testo i caratteri unicode con gli smileys prodotti da ChatGPT.
Quando si esegue uno script Bash ci sono due modalità principali da impiegare, che hanno conseguenze diverse sull’ambiente della shell.
1. Esecuzione diretta (./script.sh)
Lo script viene eseguito in un nuovo processo figlio della shell corrente.
È equivalente a lanciare: sh script.sh oppure bash script.sh (a seconda dello shebang in testa allo script).
Le variabili di ambiente create o modificate nello script non influenzano la shell madre: al termine del processo figlio vanno perse.
Lo script può però leggere le variabili esportate (export VAR=valore) dalla shell che lo ha invocato.
Quindi può solo leggere le variabili di ambiente della shell madre ma non può scriverle.
2. Sourcing (source script.sh oppure . script.sh)
Lo script viene eseguito nella shell corrente, senza avviare un processo figlio.
Tutte le modifiche a variabili, alias, funzioni o al PATHrimangono attive anche dopo l’esecuzione.
È l’approccio necessario per script che devono modificare l’ambiente, ad esempio gli script activate dei virtual environment Python. Infatti è qui che ho trovato questo comando: dovevo fare partire un ambiente virtuale Python isolato che uso per fare esperimenti con Python.
Esempio di comportamento
# file: test.sh
MYVAR="ciao"
echo "Dentro lo script: $MYVAR"
L’output del programma bash è bash test.sh: Dentro lo script: ciao ma poi se vado a vedere il contenuto della variabile di ambiente (a esecuzuone terminata) non trovo nulla: echo $MYVAR # (vuoto)
Se invece uso source e non bash source test.sh: Dentro lo script: ciao e poi tovo anche la variabile di ambiente nella shell madre: echo $MYVAR # ciao
Variabili esportate
C’è una distinzione importante tra variabili normali e variabili esportate: se dalla shell definsco due variabili di ambiente in questi due modi diversi:
Preso dalla curiosità di ripassare l’assembly (tanti anni fa studiai il Motorola 68000) ho scritto una guida ordinata che illustra passo per passo come scrivere un semplice programma Assembly in real-mode (16 bit), confezionarlo come boot-sector su floppy virtuale, e infine eseguirlo e verificarne il funzionamento tramite QEMU.
Il piccolo programma assembly, descritto nella sezione 1, prende il contenuto di una locazione di memoria e lo moltiplica per due, scrivendo il risultato in un’altra locazione di memoria. Per fare questo semplice task dobbiamo andare sul nudo metallo della macchina, saltando anche il sistema operativo.
Il programma per essere avviato deve venire collocato in una zona di disco detto boot sector: non sarà il sistema operativo a decidere dove caricarlo, ma verrà caricato da questo boot sector in una area di memoria e avviato da un emulatore del BIOS.
Dunque, a dispetto del nome (boot), in realtà non avverrà alcun boot del PC ma soltanto della macchina virtuale implementata da QEMU. Il boot sector in pratica può essere una qualsiasi zona del disco formattata nel modo che vedremo.
1. Il boot-sector
Il boot-sector è il primo settore (512 B) di un dispositivo di avvio (floppy, disco fisso, USB, …) che il BIOS (o nel nostro caso l’emulatore) legge ed esegue automaticamente all’accensione.
Per essere riconosciuto come tale dal BIOS esso deve terminare i suoi 512 byte con la sequenza di byte:
0x55 0xAA.
Questa sequenza viene detta firma diavvio e si trova neigli ultimi due byte del blocco (510 e 511). Quando un blocco termina con questa firma il BIOS sa che può caricare in memoria RAM il contenuto ed esegurilo, senza alcuna intermediazione del sistema operativo! È un po’ quello che succede al vero boot del sistema quando il BIOS interroga in sequenza i dispositivi in cui si può trovare l’avvio, carica in memoria il contenuto (che è il loader del OS) e lo avvia. Solo che qui impariamo che possiamo fare questa cosa anche in modo estemporaneo, col PC già acceso.
Anche nel nostro caso avremo il caricamento in memoria del contenuto del boot sector e l’impostazione dell’Instruction Pointer Register (IP) in modo tale cda far partire l’esecuzione del programma. Più precisamente verranno impostati due registri, CS e IP, avviando così il codice “bare-metal”.
Dunque per avviare un programmino così semplice devo avere anche un boot sector. Perché?
All’avvio, il processore i5 (come qualsiasi x86) entra in uno stato chiamato real‐mode, con il registro CS:IP inizializzato a 0xF000:0xFFF0 — un indirizzo dove risiede il firmware BIOS. Il BIOS, prima ancora del sistema operativo o kernel, cerca sugli storage (disco fisso, floppy, CD…) un “settore di boot” valido, che è un blocco di 512 byte nel quale:
Il BIOS copia quel settore in memoria all’indirizzo fisico 0x0000:0x7C00.
Controlla che gli ultimi due byte siano 0x55 e 0xAA (la “boot signature”).
Imposta con questo indiorizzo (CS:IP ← 0x0000:0x7C00) la coppia di registri Code Segment e Instruction Pointer e così avviene l’avvio del nostro piccolo programma.
Se non trova questa firma, ignora il dispositivo e passa al successivo; non esegue direttamente il nostro codice se non è formattato come boot‐sector.
Perché serve un boot‐sector anche per un “hello world” in Assembly?
Nessun OS, nessun loader: stiamo lavorando “bare metal”, senza DOS, Linux o GRUB che carichino ed eseguano un binario. Ignoriamo bellamente la presenza di GRUB e del kernel, ci prendiamo direttamente il processore.
BIOS+bootloader = unico meccanismo d’avvio: è il BIOS che governa i primissimi passi di qualsiasi PC x86 e l’unico modo per dirgli “carica ed esegui questo codice” è confezionarlo come boot‐sector. OK? quindi sfruttiamo il meccanismo primitivo di avvio per avviare picccoli programmi di esempio.
Attenzione che si potrebbero fare anche danni… Infatti i virus volentieri si installano nei boot sector perché così posssono andare in esecuzione senza alcun controllo!
512 byte bastano per tutto: il nostro programma sta in 512 byte e può iniziare a girare subito, senza filesystem né driver.
Real mode è quella modalità che ci consentirebbe di accedere liberamente a tutta la RAM?
No: è vero che in real mode non hai protezioni né paging, ma hai comunque dei limiti:
Segmentazione a 20 bit
CS, DS, ES, SS, … sono registri a 16 bit usati come basi di segmento.
L’indirizzo fisico poi si calcola così, a partire dai valori scritti dentro a questi registri:
In pratica l’indirizzo “reale” arriva fino a poco sopra 1 MiB.
A20 Gate
Per motivi di retrocompatibilità, i primi IBM-PC “chiudevano” il 21° bit, limitando l’accesso esattamente a 1 MiB (0x00000–0xFFFFF).
Disabilitando la “porta A20” si ripristinava esattamente 1 MiB di spazio. Abilitandola (A20=1) si arriva fino a quel ~1.06 MiB di cui sopra.
Nessuna protezione né paging
In real mode il codice gira con livello di privilegio massimo (CPL=0, Current Privilege Level; 0 è il privilegio del BIOS/kernel, il massimo possibile) e non c’è paging: ogni istruzione che calcola un indirizzo fisico ci arriva davvero. Ma il massimo spazio accessibile è quello definito dalla segmentazione (circa 1 MiB), non tutto il DRAM fisico se ne hai di più.
In sintesi
Real mode:
Accesso “puro” alla memoria fino a ≈1 MiB, senza nessuna protezione o traduzione.
Ottimo per il boot e per esercizi di basso livello.
Protected mode (o long mode):
Introduce descrittori, protezioni, paging e permette di raggiungere tutta la RAM fisica (e virtuale) disponibile.
Quindi in real mode non “giri libero” su tutta la RAM a disposione del porcessore i5 (che ne ha decine di gigabyte), ma giri libero solo sui primi ~1 MiB, senza protezioni. Per accedere a più memoria devi passare a protected (o long) mode.
2. Scrivere il programma Assembly
Ecco il programma che raddoppia un valore cablato nel codice e termina con hlt (halt):
; double.asm — boot-sector real-mode 16 bit
org 0x7C00
bits 16
mov al, [input] ; AL ← valore iniziale
add al, al ; AL ← 2×AL
mov [output], al ; scrivi risultato
cli ; disabilita interrupt
.hang:
hlt ; ferma il processore
input db 07h ; dato di partenza = 7
output db 00h ; qui finirà 2×7 = 14
; padding + signature
times 510-($-$$) db 0
dw 0xAA55
org 0x7C00: indica a NASM che il settore sarà caricato a 0x7C00.
bits 16: modalità real-mode.
Padding + dw 0xAA55: riempi fino a 510 B, poi scrivi la signature 55 AA in little-endian.
3. Generare il file binario
Con NASM ottengo un file piatto di 512 B contenente codice, padding e signature:
nasm -f bin double.asm -o double.bin
4. Costruire l’immagine floppy
Per simulare un floppy “1,44 MB” (80 tracce × 2 lati × 18 settori di 512 B):
Creazione del file pieno di zeridd if=/dev/zero of=floppy.img bs=512 count=2880 ‣ Crea floppy.img di 1 474 560 B (= 1,44 MB) pieno di zeri.
Iniezione del boot-sectordd if=double.bin of=floppy.img conv=notrunc ‣ Sovrascrive i primi 512 B di floppy.img con il contenuto di double.bin, mantenendo intatti i restanti settori.
5. Eseguire con QEMU
QEMU simula sia CPU che BIOS (SeaBIOS). Con questo comando monti floppy.img come drive A: e ottieni un prompt di monitor per il debug:
if=floppy: monta il file come controller floppy virtuale.
-monitor stdio: fornisce il prompt (qemu) sul terminale.
-nographic e -serial null: disabilitano la GUI e la seriale, evitando conflitti su stdin/stdout.
5.1 Avviare il codice
Al prompt (qemu), digita:
c
Il BIOS emulato carica il tuo settore in 0x7C00 e lo esegue fino all’istruzione hlt.
5.2 Verificare registri e memoria
Controlla i registri: (qemu) info registers ‣ EAX conterrà 0x0000000E (AL = 0x0E = 14).
Leggi direttamente i dati in memoria: (qemu) x/1xb 0x7C0A # byte “input” → 0x07 (qemu) x/1xb 0x7C0B # byte “output” → 0x0E
6. Perché questo flusso?
Real-mode 16 bit è il punto di partenza di qualsiasi PC x86: accesso semplice ai registri, senza protezioni né paging, limitato a ≈ 1 MiB di RAM.
Un boot-sector è l’unica forma di “loader” disponibile prima di un sistema operativo o di un bootloader più complesso (es. GRUB).
L’intero processo (NASM → double.bin → floppy.img → QEMU) replica fedelmente ciò che avviene su hardware reale, offrendo agli studenti una visione completamente “bare-metal” del funzionamento della macchina.
7. Estensioni possibili
Input da tastiera: usare int 0x16 per leggere un carattere e convertirlo da ASCII.
Moltiplicazioni avanzate: dimostrare ADD, LEA o IMUL in protected/long mode.
Protected mode 32 bit: aggiungere un semplice stub per abilitare PE in CR0 e passare a 32 bit.
Architetture diverse: emulatori come EASy68K (Motorola 68000) o Y86 per comprendere microarchitetture semplificate.
Conclusione
Questo esempio illustra come, con pochi comandi e meno di 512 byte di codice, sia possibile toccare con mano il funzionamento di un processore x86 “nudo e crudo”. È un ottimo esercizio didattico per riscoprire le origini del computing e introdurre i concetti fondamentali di boot‐loader, real-mode e interazione BIOS-hardware. Ed è anche un argomento da conoscere per essere consapevoli di come questa modalità sia utilizzata anche per compiere azioni dannose.
GeoGebra è un software open‑source per la didattica della matematica e della geometria dinamica.
Quello che intendiamo qui con “geometria dinamica” è un approccio all’insegnamento e alla sperimentazione della geometria in cui le costruzioni non sono “fisse” su carta, ma “vive”: ogni elemento può essere spostato e il disegno si aggiorna in tempo reale rispettando i vincoli geometrici impostati.
Caratteristiche principali
Interattività: punti, segmenti, rette, cerchi… possono essere trascinati con il mouse, e tutte le parti collegate si ridisegnano automaticamente.
Vincoli parametrizzati: si definiscono relazioni (perpendicolarità, parallelismo, congruenza, misura fissa di lunghezze o angoli…), e lo strumento mantiene queste condizioni anche quando modifichi le figure.
Esplorazione e scoperta: anziché leggere un teorema su un libro e poi disegnarlo staticamente, puoi sperimentare direttamente come cambiano gli angoli, le misure e le posizioni, cogliendo al volo pattern e proprietà.
Validazione immediata: se costruisci, per esempio, un quadrilatero sempre con angoli opposti supplementari, vedrai subito – spostando un vertice – che la somma dei due angoli rimane 180°.
Vantaggi didattici
Rende più intuitivi i concetti astratti: vedere una parabola “muoversi” quando cambi un punto di costruzione aiuta a capire perché la definizione funziona.
Sviluppa un approccio sperimentale e competente nella dimostrazione: l’allievo non si limita ad accettare un enunciato, ma può verificarne la validità in mille casi diversi e poi ragionare sul “perché”.
Favorisce la creatività: si possono esplorare con facilità configurazioni inedite, provare con poligoni regolari, esplorare locus geometrici…
Esempi di software
GeoGebra: probabilmente il più diffuso, combina geometria dinamica, algebra e calcolo; supporta anche la creazione di applet per il web.
Cabri Géomètre (storico), Cinderella, The Geometer’s Sketchpad, GeoMedia, ecc.
Geogebra per Gnome/Linux
Su molte distribuzioni Linux Geogebra lo si trova comodamente nel Software Center, ma scaricare il pacchetto portatile in formato tar.gz permette di avere sempre a disposizione l’ultima versione senza dipendenze aggiuntive. In questo articolo vedremo come scaricare GeoGebra, estrarre l’archivio e configurarne manualmente il lanciatore in GNOME Shell.
Per scaricare la mia versione Linux ho visitato il sito e sono andato alla sezione GeoGebra Classic 5 for Desktop,, dopodiché si procede qui: Linux Portable: Portable Linux bundle for 64-bit Linux systems (unsupported)
Siatemiamo la versione di GeoGebra scaricata nella cartella “Scaricati”, pronta per partire…
Un veloce
$ cd GeoGebra-Linux-Portable-5-2-893-2
chmod +x geogebra-portale
Il file risulta quindi eseeguibile: quando finalmente lanci l’app da terminale, la tanto desiderata icona personalizzata non compare né nella barra delle applicazioni (ne compare una generica, la rotellina dentata), né nell’elenco dei preferiti di GNOME Shell.
Eppure il file di configurazione c’era già, e sembrava perfetto:
Il tema icone di GNOME non ama i percorsi assoluti, preferisce pescare le immagini dalle sue cartelle standard.
GNOME Shell deve poter “riconoscere” la finestra in esecuzione come figlia del tuo .desktop, altrimenti usa l’icona generica e disabilita pure il clic destro → “Aggiungi ai preferiti”, che infatti non compariva nel menu di scelta del tasto destro..
Ecco come abbiamo risolto, in due mosse ben precise:
1. Installare l’icona nel tema Hicolor Abbiamo creato la cartella utente
~/.local/share/icons/hicolor/256x256/apps
e ci abbiamo piazzato dentro la PNG rinominata in “geogebra.png”. L’icona l’ho cercata col sistema di ricerca di immagini di DuckDuckGo, ho scaricato una PNG e ho prodotto le varie icone:
ha fatto il resto, rendendo disponibile l’icona a tutto il sistema.
2. Allineare il launcher al WM_CLASS dell’app Con xprop WM_CLASS abbiamo scoperto che GeoGebra identifica le sue finestre come, ad esempio, Geogebra5. A questo punto, basta aggiungere al file ~/.local/share/applications/geogebra.desktop le due righe magiche all’inizio del file:
E trasformare il .desktop in eseguibile (chmod +x …). Un rapido Alt+F2 → r (reload della shell) ed ecco l’icona nel Dash, pronta per essere aggiunta ai Preferiti con un click destro e – finalmente! – fissa nella barra delle applicazioni.
geogebra Icon gome applications
Adesso, ogni volta che avvieremo GeoGebra dalle “Attività” (il segmentino orizzontale in alto a sinistra, oppure premendo il tasto Windows), vedremo il logo corretto, che potremo fissare alla barra delle applicazioni in un lampo, senza perderci più in percorsi assoluti o icone sbagliate.
Un piccolo esercizio da vero “power user” di GNOME, e una bella lezione sulla gestione delle risorse grafiche in Linux.
Buon lavoro con GeoGebra, e buon divertimento nella personalizzazione del desktop!
Gnome open source free spftware linux desktop environment
Negli ambienti desktop basati su GNOME, come Ubuntu, è possibile impostare uno sfondo che cambia automaticamente nel tempo, come una presentazione. Quello che molti non sanno è che GNOME supporta nativamente gli slideshow tramite file XML, e che lo slideshow con il “cronometrino” visibile nella sezione Aspetto delle impostazioni è un esempio di questo meccanismo.
In questa guida vedremo come creare un nostro slideshow personalizzato con immagini a piacere, farlo comparire nella GUI di GNOME e attivarlo come sfondo dinamico.
Preparazione delle immagini
GNOME accetta solo percorsi di sistema per gli slideshow, per cui le immagini vanno copiate in una directory accessibile globalmente, come /usr/share/backgrounds/.
Per esempio, possiamo creare una nuova cartella e copiarci dentro le nostre immagini:
Lo slideshow viene definito da un file XML con una struttura precisa. Possiamo generarlo automaticamente con uno script bash. Ecco uno script che crea il file /usr/share/backgrounds/apod_slideshow.xml con durata di 30 minuti per ogni immagine e transizioni di 5 secondi:
Salva questo script in un file .sh, rendilo eseguibile con chmod +x e lancialo. Il file XML verrà generato correttamente nella directory di sistema.
Registrazione dello slideshow nella GUI
Per far apparire lo slideshow tra gli sfondi selezionabili nella sezione Aspetto, è necessario creare un file descrittore in /usr/share/gnome-background-properties/. Ecco un esempio:
Nell’opzione options è possibile impostare scaled se si vuole che l’immagine venga riscalata (come ho preferito in questo caso). I possibili valori sono riassunti in uqesta tabella
Valore
Comportamento
centered
Immagine centrata, nessun ridimensionamento
scaled
Scala per entrare nello schermo
stretched
Deforma per riempire lo schermo
zoom
Riempie mantenendo proporzioni (può sgranare)
spanned
Su più monitor, come un unico sfondo
Salva questo file come /usr/share/gnome-background-properties/apod-slideshow.xml. Dopo averlo fatto, apri di nuovo le impostazioni di GNOME: nella sezione Aspetto vedrai una nuova voce con il nome indicato nel campo <name>, accompagnata dal simbolo del cronometro. Selezionandola, attiverai lo slideshow appena creato.
Questo metodo sfrutta direttamente le funzionalità native di GNOME, senza bisogno di strumenti esterni come Variety. È ideale se vuoi uno sfondo dinamico elegante, discreto e completamente personalizzabile, che rispetti le logiche del sistema e venga integrato perfettamente nella GUI.
Puoi aggiornare le immagini quando vuoi: ti basta sostituirle nella cartella /usr/share/backgrounds/apod/ e rigenerare il file XML con lo script.
Scaricare immagini dalla NASA
Le immagini pubblicate quotidianamente dalla NASA attraverso il servizio Astronomy Picture of the Day (APOD) sono un’ottima fonte di sfondi spettacolari. Sono liberamente utilizzabili perché rilasciate nel pubblico dominio. Per scaricarle in modo automatizzato si può utilizzare l’API ufficiale messa a disposizione dalla NASA, accessibile gratuitamente previa registrazione su api.nasa.gov. Una volta ottenuta la chiave di accesso (API key), è possibile scrivere uno script che interroga l’API per ottenere l’immagine del giorno, ne estrae il collegamento ad alta risoluzione e la salva in una cartella locale.
Un esempio di script bash potrebbe interrogare l’API per un certo numero di giorni passati, scaricare le immagini disponibili e salvarle in una directory temporanea. Da lì è poi possibile copiarle in /usr/share/backgrounds/apod/, come descritto in precedenza, ed eventualmente rigenerare lo slideshow. Va tenuto presente che l’API non consente di filtrare le immagini in base alla risoluzione o all’orientamento, quindi potrebbe essere necessario un controllo manuale o automatico a posteriori, ad esempio per escludere immagini verticali o troppo piccole.
In questo modo è possibile costruire uno slideshow di sfondi aggiornato con immagini astronomiche sempre nuove, sincronizzate con la pubblicazione quotidiana della NASA.
Negli ultimi giorni ho condotto una piccola sperimentazione con Whisper, il modello di riconoscimento vocale automatico (ASR) open source sviluppato da OpenAI. L’obiettivo era duplice:
Registrare l’audio del sistema in modo pulito (senza passare dal microfono)
Valutare le prestazioni e l’accuratezza dei modelli tiny, base e small di Whisper, cercando una misura sintetica della loro “efficienza complessiva”
Cos’è Whisper
Whisper consente di trascrivere il parlato contenuto in un file audio producendo un file di testo.
E’ un sistema di riconoscimento vocale automatico (Automatic Speech Recognition, ASR) rilasciato da OpenAI nel 2022. È basato su una rete neurale di tipo transformer e addestrato su un enorme corpus di dati multilingue e multitask. Whisper è capace di:
Trascrivere audio parlato in testo
Tradurre automaticamente parlato in inglese
Riconoscere e segmentare parlato in presenza di rumore di fondo
Uno degli aspetti più interessanti è che Whisper è open source e facilmente utilizzabile da linea di comando o come libreria Python. Supporta vari modelli di dimensioni crescenti, dal più piccolo (tiny) al più grande (large), con diversi trade-off tra velocità e accuratezza.
Registrazione pulita con PulseAudio e Audacity
Utilizzando pavucontrol su Ubuntu, è possibile registrare direttamente ciò che il sistema riproduce, senza microfoni.
Infatti in prima battuta facevo funzionare il browser che riproduceva il video e registravo l’audio con il microfono del PC: un setup abastanza ingenuo e primitivo.
La chiave è selezionare come sorgente di registrazione:
Monitor of Built-in Audio Analog Stereo
In Audacity basta:
Premere “Record”
Selezionare la sorgente giusta da pavucontrol (scheda “Registrazione”)
Il risultato è una traccia audio digitale e pulita, ideale per testare Whisper.
Trascrizione automatica con Whisper
Whisper supporta modelli di diverse dimensioni, con un compromesso tra:
Velocità di esecuzione (più piccolo è il modello, più è veloce)
Qualità della trascrizione (i modelli più grandi sono più accurati)
I comandi utilizzati:
whisper test.wav --language Italian --model small --output_dir small --output_format all
Ripetuto per tiny, base e small, salvando i risultati in sottodirectory dedicate.
Una tabella riassuntiva sui modelli ci mostra le caratteristiche di ognuno:
Modello
Parametri
Dimensione file
Note
tiny
≈ 39 milioni
~75 MB
Velocissimo, ma meno preciso
base
≈ 74 milioni
~142 MB
Buon compromesso leggero
small
≈ 244 milioni
~462 MB
Più lento, ma molto più accurato
La metrica che unisce qualità e prestazioni
Durante il confronto, ho voluto trovare una figura di merito (FdM) che combinasse:
WER (Word Error Rate): misura quanto il testo trascritto è fedele
RTF (Real-Time Factor): tempo impiegato per trascrivere diviso la durata dell’audio
La formula che ho adottato è:
\textit{FdM} = \frac{1-\textit{WER}}{1+RTF}
Più è alta, migliore è il modello.
Risultati su un frammento audio “sporco”
Test su una frase:
Il sistema SRFC si rivolge a persone con esperienza maturata in contesti di istru…
Risultati:
Modello | Durata audio | Tempo impiegato | RTF | WER | FdM
-----------------------------------------------------------------------
tiny | 8.00s | 0.65s | 0.08 | 28.57% | 0.66
base | 8.00s | 0.91s | 0.11 | 35.71% | 0.58
small | 7.00s | 2.37s | 0.34 | 7.14% | 0.69
Osservazioni:
small è il più accurato, nonostante sia più lento
tiny sorprende: pur essendo meno preciso, ha una FdM superiore a base
base in questo caso è il peggiore compromesso
Specifiche del sistema di test
Tutti i benchmark sono stati eseguiti su una macchina con le seguenti caratteristiche:
Sistema operativo: Ubuntu con Whisper in ambiente venv (Python 3.12)
Note: elaborazione solo su CPU, senza accelerazione GPU
Considerazioni finali
Questa esperienza mostra innanzitutto che una registrazione pulita è fondamentale per la qualità della trascrizione; l’accuratezza e la velocità possono essere combinate in una metrica utile. Infine la dimensione small del modello è un ottimo compromesso su CPU se si accetta un RTF più alto
Il pensiero di combinare RTF e WER in un indice sintetico è nato spontaneamente durante il lavoro: un piccolo segnale che la mente umana ha ancora margine per affiancare (e talvolta superare) l’intelligenza artificiale.
Note bibliografiche
RTF (Real-Time Factor) è definito come il rapporto tra il tempo di elaborazione e la durata del file audio. Se un sistema ha un RTF = 1, significa che lavora in tempo reale. Vedi anche:
Utilizzo intercambiabilmente due PC e preferisco mantenere in locale (non su cloud) i contentuti di due directory, per maggior sicurezza.
Nell’ambito di una qualsiasi rete locale in cui collego i due pc voglio che una volta al giorna queste irectory vengano sincronizzate.
Solitamente utilizzo Samba per collegare la directory di PC1 montandola in PC2. L’uso di GVFS però non consente a rsync di lavorare bene perché non riesce la gestione dei diritti di accesso dei file.
Ho superato questo problema smontando la direcory remota e rimontandola a mano con mount.
Quindi le tre operazioni da fare sono:
montare in PC2 la directory /home/marcob/clienti/#PC1
lanciare rsync
creare un cron job per eseguire questo allineamento una volta al giorno mentre sono in pausa.
Ora però non voglio specificare l’indirizzo IP, preferendo affidarmi piuttosto al DNS (o al file /etc/hosts), in modo tale che lo script funzioni indipendentemente dalla rete in cui mi trovo.
Una seconda tecnica che voglio utilizzare è quella dei secrets in mofdo tale che le informazioni riservate come le credensiali di accesso non siano scritte nello script ma vengano lette da un file locale di configurazione accessibile solo al processo.
La terza cosa che desidero è che tutti i parametri non sensibii siano scitti un un secondo file di configurazione.
rsync ersione finale
La versione finale avrà dunque tre file principali:
Lo script di sincronizzazione (sync_samba.sh)
Il file di configurazione (samba_sync.conf)
Il file dei secrets (/etc/samba/sync_credentials)
Creazione del file di configurazione
Crea un file chiamato samba_sync.conf per definire i parametri di montaggio e sincronizzazione:
# File di configurazione: samba_sync.conf
# Nome host o IP della condivisione Samba
SERVER="js"
# Nome della condivisione Samba
SHARE="sambashare"
# Directory di mount
MOUNT_POINT="/mnt/sambashare"
# Percorso locale dei file da sincronizzare
LOCAL_PATH="/home/marco/Documenti/clienti/"
# Percorso remoto nella condivisione Samba
REMOTE_PATH="clienti/"
# Versione del protocollo SMB (modificabile se necessario)
SMB_VERSION="3.0"
# Percorso del file dei secrets (non deve essere leggibile da altri utenti!)
CREDENTIALS_FILE="/etc/samba/sync_credentials"
Salvo questo file nella directory /etc/samba/ così posso condividerlo tra più script.
Creazione del file dei secrets (per sicurezza)
Creiamo il file /etc/samba/sync_credentials per contenere le credenziali:
username=marcob
password=XXXXX
Salvo con permessi restrittivi per evitare che altri utenti possano leggerlo:
sudo chmod 600 /etc/samba/sync_credentials
Script di sincronizzazione (sync_samba.sh)
Ora creiamo lo script sync_samba.sh per montare, sincronizzare e smontare la condivisione.
#!/bin/bash
# Carica il file di configurazione
CONFIG_FILE="$(dirname "$0")/samba_sync.conf"
if [ ! -f "$CONFIG_FILE" ]; then
echo "Errore: File di configurazione '$CONFIG_FILE' non trovato!"
exit 1
fi
source "$CONFIG_FILE"
# Controlla che il file delle credenziali esista
if [ ! -f "$CREDENTIALS_FILE" ]; then
echo "Errore: File delle credenziali '$CREDENTIALS_FILE' non trovato!"
exit 1
fi
# Controlla se la condivisione è già montata
if mountpoint -q "$MOUNT_POINT"; then
echo "La condivisione è già montata su $MOUNT_POINT"
else
echo "Montando la condivisione Samba..."
sudo mount -t cifs "//$SERVER/$SHARE" "$MOUNT_POINT" -o credentials="$CREDENTIALS_FILE",uid=$(id -u),gid=$(id -g),file_mode=0777,dir_mode=0777,vers=$SMB_VERSION
if [ $? -ne 0 ]; then
echo "Errore: Impossibile montare la condivisione Samba."
exit 1
fi
fi
# Esegue la sincronizzazione con rsync
echo "Avvio della sincronizzazione..."
rsync -av --progress "$LOCAL_PATH" "$MOUNT_POINT/$REMOTE_PATH"
if [ $? -eq 0 ]; then
echo "Sincronizzazione completata con successo."
else
echo "Errore durante la sincronizzazione!"
exit 1
fi
# Smonta la condivisione
echo "Smontando la condivisione..."
sudo umount "$MOUNT_POINT"
if [ $? -eq 0 ]; then
echo "Condivisione smontata correttamente."
else
echo "Attenzione: impossibile smontare la condivisione!"
exit 1
fi
Rendiamolo eseguibile:
chmod +x sync_samba.sh
Utilizzo dello script
Ora possiamo eseguire il tuo script in qualsiasi rete, senza bisogno di specificare l’IP:
✔ Sicurezza: Le credenziali sono protette e non visibili nello script. ✔ Flessibilità: Il file di configurazione permette di cambiare i parametri senza modificare lo script. ✔ Automazione: Puoi schedulare l’esecuzione con cron. ✔ Adattabilità: Funziona su diverse reti senza bisogno di cambiare IP.
Utilizziamo tecnologie come i cookie per memorizzare e/o accedere alle informazioni del dispositivo. Lo facciamo per migliorare l'esperienza di navigazione e per mostrare annunci personalizzati. Il consenso a queste tecnologie ci consentirà di elaborare dati quali il comportamento di navigazione o gli ID univoci su questo sito. Il mancato consenso o la revoca del consenso possono influire negativamente su alcune caratteristiche e funzioni.
Funzionale
Sempre attivo
L'archiviazione tecnica o l'accesso sono strettamente necessari al fine legittimo di consentire l'uso di un servizio specifico esplicitamente richiesto dall'abbonato o dall'utente, o al solo scopo di effettuare la trasmissione di una comunicazione su una rete di comunicazione elettronica.
Preferenze
L'archiviazione tecnica o l'accesso sono necessari per lo scopo legittimo di memorizzare le preferenze che non sono richieste dall'abbonato o dall'utente.
Statistiche
L'archiviazione tecnica o l'accesso che viene utilizzato esclusivamente per scopi statistici.L'archiviazione tecnica o l'accesso che viene utilizzato esclusivamente per scopi statistici anonimi. Senza un mandato di comparizione, una conformità volontaria da parte del vostro Fornitore di Servizi Internet, o ulteriori registrazioni da parte di terzi, le informazioni memorizzate o recuperate per questo scopo da sole non possono di solito essere utilizzate per l'identificazione.
Marketing
L'archiviazione tecnica o l'accesso sono necessari per creare profili di utenti per inviare pubblicità, o per tracciare l'utente su un sito web o su diversi siti web per scopi di marketing simili.
Commenti recenti