In che modo questo "&" alla fine del mio comando ha reso lo script così veloce?


18

Durante la risoluzione di alcune sfide CTF online, mi sono imbattuto in una situazione in cui avevo bisogno di rinforzare un server. Questo è il codice che ho scritto:

#!/bin/bash

for i in {0..9}{0..9}{0..9}{0..9} 
    do
    echo "Now trying code.."
    echo $i
    echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt
    done

Questo è stato incredibilmente, dolorosamente lento . Avevo bisogno di provare combinazioni da 1000 a 9999 e questo impiegava circa 5 secondi per ogni 10 tentativi. Quindi, seguendo un consiglio, ho inserito un '&' alla fine di questa riga:

   echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt &

E, ha provato centinaia di combinazioni in pochi secondi. Ero molto sorpreso. Qualcuno potrebbe spiegarmi la logica? Cosa ha fatto il '&'?


3
Ti suggerisco di leggere il manuale della shell. &fa funzionare il comando in background, tutto qui. Non lo ha reso più veloce o altro. Leggi il manuale di qualunque shell tu stia usando (presumo bash).
polemon

Lo ha fatto funzionare in background, dovresti vederlo in realtà è finito.
DisplayName

7
Non vuoi testare sotto 1000? Si prega di utilizzarefor i in {1000..9999}
Walter A

2
È possibile che abbia reso l'esecuzione dello script più veloce poiché le porte ora stanno scadendo in parallelo. Dovresti includere waita alla fine, comunque.
Bratchley

Hai guardato nc -z localhost 1000-2000?
Walter,

Risposte:


30

L'aggiunta &genera un processo in background.

Se scrivi a; b, eseguirà il comando a, attendi che finisca, quindi esegui il comando b, in sequenza.

Se scrivi a & b, verrà generato acome processo in background. Non aspetterà che finisca e inizierà a funzionare bimmediatamente. Funzionerà entrambi contemporaneamente.

Puoi vedere cosa fa sperimentando nella shell. Se hai Xinstallato, xtermè un buon modo per vedere cosa succede: digitando

$ xterm

causerà l'apertura di un'altra finestra del terminale e il primo attenderà fino alla sua chiusura. Solo quando lo chiudi riavrai la tua shell. Se digiti

$ xterm &

quindi lo eseguirà in background e riavrai immediatamente la shell, mentre anche la xtermfinestra rimarrà aperta.

Quindi se scrivi

echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt

stabilisce la connessione, invia la stringa, memorizza ciò che esce nel file e solo successivamente passa a quello successivo.

Aggiungendo il &non aspettare. Finirà per eseguirli tutti o diecimila più o meno contemporaneamente.

La tua sceneggiatura sembra "terminare" più rapidamente, perché probabilmente non è finita in quel momento. Ha appena fatto diecimila lavori in background e poi ha concluso quello in primo piano.

Ciò significa anche che, nel tuo caso, proverà ad aprire diecimila connessioni più o meno contemporaneamente. A seconda di ciò che l'altra estremità può gestire, alcuni potrebbero non riuscire. Non solo, ma non vi è alcuna garanzia che funzioneranno in ordine, in realtà quasi sicuramente non lo faranno, quindi ciò che effettivamente finirà /tmp/me/dump.txtè l'ipotesi di qualcuno.

Hai verificato se l'output era corretto?


2
Sì, ho risolto la sfida. Il server doveva rispondere con la password se veniva fornito il codice corretto. Ho eseguito questo comando per controllare 'dump.txt': $ cat dump.txt | sort | uniq -u ..e la riga contenente la password corretta mi è stata rivelata.
discenteX

16
@intellikid: non intendo essere scortese, ma ha funzionato per pura fortuna. Non solo l'ordine non importava, le risposte del server erano più piccole del ncbuffer di scrittura. Se così non fosse, le risposte del server sarebbero state probabilmente intercalate. Cioè, se avessi avuto un buffer di scrittura di 1 byte, e le risposte fossero 1111e 2222, probabilmente avresti visto qualcosa di simile 11221212piuttosto che un ordinatamente separato 1111 2222.
Marin

Sì, l'ho capito. Ecco perché sto giocando a questi giochi di guerra. Imparo ad ogni livello. Grazie per aiutare questo apprendimento.
discenteX

2

Il comando nc (netcat) è costoso, in termini di tempo. Deve connettersi al server remoto, inviare i dati, attendere una risposta e restituirli.

Utilizzando & stai fondamentalmente biforcando quel comando in un processo in background (si chiama un "lavoro"). Di per sé ciò non lo fa correre più veloce. Ma significa che il tuo ciclo non è più bloccato e può già fare la prossima iterazione (con il prossimo nc).

Quindi, in sostanza, la tua velocità è causata dal fare tutte queste connessioni remote in parallelo dove altrimenti dovrebbero attendere il completamento della precedente.

A proposito, a seconda del tuo terminale, i comandi echo possono anche rallentare il tuo ciclo (a volte hanno bisogno di aspettare fino a quando non c'è spazio nel buffer di scrittura).

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.