Qual è il modo più diretto per creare un file "virtuale" in Linux, che consentirebbe l'operazione di lettura su di esso, restituendo sempre l'output di qualche particolare comando (eseguito ogni volta che il file viene letto da)? Pertanto, ogni operazione di lettura causerebbe un'esecuzione di un comando, rilevandone l'output e passandolo come "contenuto" del file.Come creare un file di comando virtuale con comando in Linux?
risposta
Non esiste alcun modo per creare un cosiddetto "file virtuale". D'altra parte, si sarebbe in grado di ottenere questo comportamento implementando il semplice synthetic filesystem nello spazio utente tramite FUSE. Inoltre non è necessario utilizzare c, lì sono collegamenti anche per linguaggi di scripting come python.
Modifica: E probabile che esista già qualcosa di simile: vedere ad esempio scriptfs.
Ho paura che questo non sia facilmente possibile. Quando un processo viene letto da un file, utilizza chiamate di sistema come open
, fstat
, read
. Dovresti intercettare queste chiamate e produrre qualcosa di diverso da ciò che restituirebbe. Ciò richiederebbe la scrittura di una sorta di modulo del kernel, e anche allora potrebbe rivelarsi impossibile.
Tuttavia, se è sufficiente per far scattare qualcosa ogni volta che un certo file si accede, si potrebbe giocare con inotifywait
:
#!/bin/bash
while inotifywait -qq -e access /path/to/file; do
echo "$(date +%s)" >> /tmp/access.txt
done
Esegui questo come un processo in background, e si otterrà una voce in /tmp/access.txt
ogni volta il tuo file viene letto.
Nessuno ha menzionato questo ma se è possibile scegliere il percorso del file è possibile utilizzare lo standard input /dev/stdin
.
Ogni volta che il programma cat
viene eseguito, si finisce per leggere l'uscita della scrittura programma al tubo che è semplicemente echo my input
qui:
for i in 1 2 3; do
echo my input | cat /dev/stdin
done
uscite:
my input
my input
my input
Questo è un great answer I copiato di seguito.
Fondamentalmente, named pipes consente di farlo nello scripting e Fuse facciamolo facilmente in Python.
Forse stai cercando un named pipe.
mkfifo f
{
echo 'V cebqhpr bhgchg.'
sleep 2
echo 'Urer vf zber bhgchg.'
} >f
rot13 < f
La scrittura sul tubo non avvia il programma di ascolto. Se si desidera elaborare l'input in un ciclo, è necessario mantenere in esecuzione un programma di ascolto.
while true; do rot13 <f >decoded-output-$(date +%s.%N); done
Si noti che tutti i dati scritti nella pipe vengono uniti, anche se ci sono più processi di scrittura. Se più processi stanno leggendo, solo uno ottiene i dati. Quindi un tubo potrebbe non essere adatto a situazioni concorrenti.
Un socket denominato può gestire connessioni simultanee, ma questo è oltre le funzionalità per gli script di shell di base.
Al più complessa estremità della scala sono custom filesystems, che permette di disegnare e montare un filesystem in cui ogni open
, write
, ecc, attiva una funzione in un programma. L'investimento minimo è di decine di righe di codifica non banale, ad esempio in Python. Se si desidera solo eseguire comandi durante la lettura dei file, è possibile utilizzare scriptfs o fuseflt.
Grazie, scriptfs sembra esattamente quello che stavo cercando :-) –
Quindi, qual è 'cat/proc/cpuinfo'? –
@MichaelCole: cpuinfo non è un file isolato, fa parte del filesystem proc. L'altra differenza è che procfs è implementato nel kernel, mentre questa domanda richiede una soluzione in userspace. – marbu