Vraag Hoe differentieer ik de uitvoer van twee commando's?


Ik had me voorgesteld dat de eenvoudigste manier om de inhoud van twee vergelijkbare mappen te vergelijken, iets zou zijn

diff `ls old` `ls new`

Maar ik begrijp waarom dit niet werkt; diff krijgt een grote lange lijst met bestanden op de opdrachtregel, in plaats van twee streams zoals ik had gehoopt. Hoe pas ik de twee uitgangen direct naar diff door?


133
2017-12-15 22:01


oorsprong


Verwant: Hoe kan ik de uitvoer van twee unix-opdrachten vergelijken om het verschil te vinden?, Diff output van twee programma's zonder tijdelijke bestanden - kenorb


antwoorden:


Commandosubstitutie `…` vervangt de uitvoer van de opdracht in de opdrachtregel, dus diff ziet de lijst met bestanden in beide mappen als argumenten. Wat je wilt is voor diff om twee bestandsnamen op de opdrachtregel te zien en de inhoud van deze bestanden als directoryvermeldingen te hebben. Dat is wat procesvervanging doet.

diff <(ls old) <(ls new)

De argumenten voor diff zal lijken op /dev/fd/3 en /dev/fd/4: het zijn bestandsdescriptors die overeenkomen met twee pijpen gemaakt door bash. Wanneer diff opent deze bestanden, het wordt verbonden met de leeszijde van elke pijp. De schrijfzijde van elke pijp is verbonden met de ls opdracht.


194
2017-12-15 22:06



echo <(echo) <(echo) nooit gedacht dat dit zo interessant zou kunnen zijn: D - Aquarius Power
Procesvervanging is niet ondersteund door alle shells, maar pipe-omleidingen zijn een nette oplossing. - Irfan434
Om maar te zwijgen over het feit dat het ontleden van ls niet wordt aanbevolen unix.stackexchange.com/questions/128985/why-not-parse-ls - Katu
@Katu Het probleem met ls is dat het bestandsnamen versmelt. Het parseren van de uitvoer is fragiel (het werkt niet met "rare" bestandsnamen). Voor het vergelijken van twee directoryvermeldingen is het ok zolang de uitvoer ondubbelzinnig is. Met willekeurige bestandsnamen zou dit een optie zoals vereisen --quoting-style=escape. - Gilles


Vis schaal

In Fish shell moet je inpluizen PSUB. Hier is een voorbeeld van vergelijking met heroku en dokku config met Niet te vergelijken:

bcompare (ssh me@myapp.pl dokku config myapp | sort | psub) (heroku config -a myapp | sort | psub)

2
2018-04-12 07:34



Een ander grafisch diff-hulpmiddel is meld die open source is en beschikbaar is in de Ubuntu- en EPEL-repositories. meldmerge.org - phiphi


Voor zsh, gebruiken =(command) maakt automatisch een tijdelijk bestand en vervangt het =(command) met het pad van het bestand zelf. Met Command Substitution, $(command) is vervangen door de uitgang van het commando.

Er zijn dus drie opties:

  1. Commandosubstitutie: $(...) 
  2. Procesvervanging: <(...)
  3. zsh-Geparfumeerde procesvervanging: =(...)

zs-gearomatiseerde procesvervanging, # 3, is erg handig en kan op dezelfde manier worden gebruikt om de uitvoer van twee opdrachten te vergelijken met behulp van een diff-tool, bijvoorbeeld Beyond Compare:

bcomp  =(ulimit -Sa | sort) =(ulimit -Ha | sort)

Let op: voor Beyond Compare moet je gebruiken bcomp voor het bovenstaande (in plaats van bcompare) sinds bcomp lanceert de vergelijking en wacht om het te voltooien. Als je gebruikt bcompare, waarmee een vergelijking wordt gestart en deze onmiddellijk wordt afgesloten waardoor de tijdelijke bestanden die zijn gemaakt om de uitvoer van de opdrachten op te slaan verdwijnen.

Lees hier meer: http://zsh.sourceforge.net/Intro/intro_7.html

Merk ook dit op:

Merk op dat de shell een tijdelijk bestand maakt en het verwijdert wanneer de opdracht is voltooid.

en het volgende dat het verschil is tussen de twee soorten procesvervanging ondersteund door zsh (d.w.z. # 2 en # 3):

Als u de man-pagina van zsh leest, merkt u wellicht dat <(...) een andere vorm van procesvervanging is die vergelijkbaar is met = (...). Er is een belangrijk verschil tussen de twee. In het geval <(...) maakt de shell een named pipe (FIFO) in plaats van een bestand. Dit is beter, omdat het het bestandssysteem niet vult; maar het werkt niet in alle gevallen. Als we in de voorbeelden hierboven = (...) hadden vervangen door <(...), zouden ze allemaal gestopt zijn met werken behalve fgrep -f <(...). Je kunt een pijp niet bewerken of openen als een e-mailmap; fgrep heeft echter geen probleem met het lezen van een lijst met woorden uit een pijp. Je kunt je afvragen waarom diff <(foo) bar niet werkt, omdat foo | diff - bar werkt; dit komt omdat diff een tijdelijk bestand maakt als het merkt dat een van zijn argumenten - is, en dan de standaardinvoer kopieert naar het tijdelijke bestand.

Referentie: https://unix.stackexchange.com/questions/393349/difference-between-subshells-and-process-substitution


2
2018-06-29 08:59



$(...) is geen procesvervanging, dat is het wel opdracht substitutie. <(...) is procesvervanging. Dat is de reden waarom de aangehaalde passage niet vermeldt $(...) helemaal niet. - muru