I comandi di Cygwin 2.9.0 cat / tac non riescono su file di grandi dimensioni durante il piping a grep -q -m1


2

Sto riscontrando un comportamento strano utilizzando Cygwin x64 2.9.0 su Windows 10 Pro x64. Il comando che sto tentando di eseguire è il seguente:

tac <file> | grep -q -m1 -F "literal string"

Il comando sopra ha esito positivo su tutti i piccoli file che lancio (piccolo significa <= 15kB). Ha anche successo se l'occorrenza finale di literal stringè vicino all'inizio del file (ad esempio, literal stringappare nella parte superiore del file e da nessun'altra parte). Infine, riesce anche quando nessuno dei flag { -q, -m1} viene passato al grepcomando.

Tuttavia, quando il file è di circa 680 KB e literal stringappare vicino alla fine del file, il taccomando stampa "tac: errore di scrittura" su STDERR. Nonostante questo errore, sembra che il comando sia riuscito, stampando la riga corrispondente sull'output (quando il -qflag viene omesso) e ottenendo il valore di ritorno appropriato da grep.

Ulteriori test hanno rivelato che questo stesso errore si verifica durante l'utilizzo cat, ad eccezione del fatto che literal stringdeve apparire vicino all'inizio del file per generare l'errore, e l'errore generato è "cat: errore di scrittura: nessuno spazio lasciato sul dispositivo".

Si noti che ciò si verifica solo se almeno una delle opzioni { -m1, -q} viene passata al grepcomando, la corrispondenza si trova vicino alla prima riga elaborata del file (poiché catè vicino all'inizio, tacperché è vicino alla fine) e il il file è grande.

Ho eseguito il dfcomando e riporta 14 MB disponibili sull'unità Cygwin, con 60 GiB liberi sul disco effettivo. So che potrei semplicemente reindirizzare STDERR al dispositivo NUL, ma sembra un bizzarro rimedio. Qualcuno sa come risolverlo correttamente?

INIZIA MODIFICA

Ho trovato un'altra segnalazione dello stesso errore a partire da maggio 2017, ma non è stata presentata alcuna soluzione. L'OP dell'altro post indica che pensa che questa sia una limitazione della dimensione del buffer delle pipe (forse su Windows, forse su Cygwin).

Risposte:


0

Ho scoperto alcune soluzioni alternative. Basta cambiare il comando:

tac <file> | grep -q -m1 -F "literal string"

a uno di:

bash -c "tac <file> | grep -q -m1 -F 'literal string'"
stdbuf -o L tac <file> | grep -q -m1 -F "literal string"

Penso che il primo funzioni perché sta usando una pipe Linux, e il secondo perché forza l' tacoutput del comando al buffer di linea. Entrambe queste forme fanno scomparire l'errore.

Dato che funziona, suppongo che il problema sia che grepinterrompe l'elaborazione del buffer di input una volta trovata la prima corrispondenza, ma taccontinua a elaborare l'input. Una volta che il buffer è pieno (probabilmente 64 kB), il buffer si blocca ed tacesce con l'errore specificato. Tuttavia, poiché tacho elaborato con successo la linea a cui tengo prima di andare in crash, tutto funziona come previsto.

Il tempismo di queste opzioni indica che la chiamata a bashè l'opzione più veloce. Ciò è probabilmente dovuto al fatto che l'utilizzo della pipe di Linux tacè in grado di tornare immediatamente una volta greptrovata la prima corrispondenza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.