Ändra ordning på pipes (a|b|c -> a|(b|c))

Permalänk
Medlem

Ändra ordning på pipes (a|b|c -> a|(b|c))

Jag har tre kommandon a,b,c. b|c blir ett nytt program, som ska få input från a. Jag kan inte bara skriva a|b|c, för då skickas programmen till varandra i fel ordning. a|(b|c) ger syntax error. Skriver jag a|{b|c} så hittas inte kommandona av någon anledning. {a;b}|c ger fel resultat, eftersom både a och b då skickas till c. Hur ska jag skriva?

Exempel:

printf "import sys\nprint sys.stdin.next()" | python

är ett program som tar lite input och skriver ut första tecknet. Hur kan jag koppla

printf "hooray!"

till detta program? Resultatet skulle alltså bli ett "h".

Obs: jag vill inte ha nåt alternativt sätt att lösa det på, som att skriva ett enskilt program för allt. Jag vill ha ett det i en enda rad, eller få veta att det jag vill göra inte går.

Tack på förhand!

Visa signatur

:€

Permalänk
Medlem

Nu hänger jag inte riktigt med på vad du menar; alla pipes går ju vidare till nästa, t.ex:

$ ls
INSTALL commands dead_keys langen missing.py result2 sortlang
READMEsv dead_key_test dead_mod langsv plugin result_dead
$ ls | grep a | grep ds
commands

Outputen från första går förbi pipen till nästa kommando, outputen efter det gör samma sak på nästa pipe o.s.v. Är du säker på att du inte gjort fel någonannanstans?

Visa signatur

Stationär: Intel-baserad, Arch + KDE
Bärbar: Dell XPS 13, Arch + KDE

Permalänk
Medlem

Läste du mitt exempel?

Om man skriver

printf "hooray!" | printf "kod" | python

så är det samma sak som

printf "kod" | python

eftersom printf "kod" inte tar nån input, och alltså blir hela raden ett program som väntar på nån input som inte kommer.

Visa signatur

:€

Permalänk

Är inte riktigt säker på vad du vill göra, men ett sätt att lägga ihop outputen från de två printf-satserna (som jag tror du försökte göra i sista inlägget?) kan ju vara följande:

echo "`printf "hooray!"` `printf "kod"`" | python

Permalänk
Medlem

Om jag byter ut "kod" mot koden i mitt först inlägg, så klagar den på omatchade paranteser. Om jag byter ut det mot "print 1" så klagar den på omatchade backticks.

Jag tycker inte jag formulerat mig oklart. Skriver man a|b|c så evalueras det som (a|b)|c. Jag vill helt enkelt evaluera a|(b|c), men den syntaxen är inte tillåten, så jag undrar hur man egentligen skriver, om det går.

Visa signatur

:€

Permalänk
Hedersmedlem

Så här?

echo hooray | tee >(python <(echo "import sys\nprint sys.stdin.next()"))

EDIT: Det där kommer för övrigt att skriva ut hooray, för enbart 'h' är det sys.stdin.next()[:1] som gäller.
EDIT2: I Bash så får man köra på printf istället för echo.

Visa signatur

Vim
Kinesis Classic Contoured (svart), Svorak (A5)
Medlem i signaturgruppen Vimzealoter.

Permalänk
Medlem

Får felmeddelande "Missing name for redirect".

Visa signatur

:€

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av eighty
Jag tycker inte jag formulerat mig oklart. Skriver man a|b|c så evalueras det som (a|b)|c. Jag vill helt enkelt evaluera a|(b|c), men den syntaxen är inte
tillåten, så jag undrar hur man egentligen skriver, om det går.

Tror missat lite hur pipe fungerar.

Om man skrivar a|b|c så skickar a' s så kopplas a stdout ihop med b's, b's stdout kopplas ihop med c's stdin.

Om man blandar in () så innebär det att kommandona innanför startas i ett nytt shell, ett sätt att använda det på är: "tar cpf - foobar | (cd /tmp; tar xvpf -)" vilket gör att filen/kataloge foobar kopieras mha tar kommandona till /tmp.

Lite oklar vad du vill göra men är det så att du vill att både a's stdout pch b's stdout skall skickas till c (utan att a går via b)så går inte det att göra med pipe.

/red: varför inte lägga python kommandona i en fil, ex. foobar.py

#!/usr/bin/python import sys print sys.stdin.next()

sedan kör du den med: printf "hooray" |foobar.py

Visa signatur

Kriga mot min brute: http://gunnard.se.mybrute.com om du vågar :D

Permalänk
Medlem

Jag sade specifikt att jag inte ville skriva ett enskilt program för allt. Kommandona jag tog upp var bara exempel.

När jag skriver (a|b)|c så menar jag rent matematiskt att a:s output skickas till b, vars output sedan skickas till c. Jag vill helt enkelt skicka b:s output till c, och sedan skicka a:s output till resulterande program.

Jag kanske har missförstått vad det är som händer när man gör printf "kod" | python. Kan det vara så att det nu inte går att skicka något till det interpreterade python-programmets stdin? På nåt sätt borde det väl gå, men kanske inte med en pipe. Isf hur?

Och jag kanske skulle behöva läsa upp på hur |, <, >, >>, (), {}, etc, fungerar. Kan jag få en länk till en uttömmande tutorial/referens på detta? Jag har googlat men bara hittat skit.

Visa signatur

:€

Permalänk
Hedersmedlem
Citat:

Ursprungligen inskrivet av eighty
Får felmeddelande "Missing name for redirect".

Konstigt, för mig i zsh (lade till lite text för att skilja):

> echo hooray | tee >(python <(echo "import sys\nprint 'Line: ' + sys.stdin.next()")) hooray Line: hooray

I Bash måste jag dock använda raden

echo hooray | tee >(python <(printf "import sys\nprint 'Line: ' + sys.stdin.next()"))

men det ger samma resultat.

Visa signatur

Vim
Kinesis Classic Contoured (svart), Svorak (A5)
Medlem i signaturgruppen Vimzealoter.

Permalänk
Medlem

Ok, det funkar i zsh och bash, men ett problem är ju att den skriver ut "hooray" i vilket fall som helst. Det ska den inte. Om vi byter ut next() mot read(1), så ska den bara skriva ut "h", inget annat.

I tcsh/csh får jag felmeddelandet "Missing name for redirect". I DOS/windows-konsoll får jag felmeddelandet "The system cannot find the file specified.". Det tycker jag är lite skumt för alla hanterar ju |, <, > på samma sätt... är det paranteserna som hanteras olika?

Visa signatur

:€

Permalänk
Hedersmedlem

Jo, sådana där pipes fungerar inte i något annat än Bash och zsh vad jag vet.

För att få bort det där med första hooray så kan man lägga till

> /dev/null

på slutet, lite fult men det fungerar.

>( och <( är lite annorlunda än > och < för sig.

Läs mer här: http://www2.linuxjournal.com/article/2156

Visa signatur

Vim
Kinesis Classic Contoured (svart), Svorak (A5)
Medlem i signaturgruppen Vimzealoter.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av eighty
Jag sade specifikt att jag inte ville skriva ett enskilt program för allt. Kommandona jag tog upp var bara exempel.

Varför inte, det gör allt så mycket enklare!

Visa signatur

Kriga mot min brute: http://gunnard.se.mybrute.com om du vågar :D

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av GunnarD
Varför inte, det gör allt så mycket enklare!

Eftersom det bara var ett exempel. Jag ville veta om det jag ville göra gick att göra med pipes. Om man kan skriva a|b så finns det ingen som helst anledning att skriva ett program som gör samma sak, kompilera, och sedan köra det.

m0rec: tack, ska kolla på det.

Visa signatur

:€

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av eighty
Eftersom det bara var ett exempel. Jag ville veta om det jag ville göra gick att göra med pipes. Om man kan skriva a|b så finns det ingen som helst anledning att skriva ett program som gör samma sak, kompilera, och sedan köra det.

Nej, men eftersom du i ditt exempel "pipade" in ett program till python som sedan i sin tur skulle få indata via pipe så skulle jag lagt programmet i en körbar fil, det hadde varit mycket enklare, och "komileringen" kommer du inte ifrån eftersom python gör det i bägge fallen.

Visa signatur

Kriga mot min brute: http://gunnard.se.mybrute.com om du vågar :D