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

Trädvy Permalänk
Medlem
Plats
R^n
Registrerad
Maj 2003

Ä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!

:€

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Jun 2005

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?

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

Trädvy Permalänk
Medlem
Plats
R^n
Registrerad
Maj 2003

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.

:€

Trädvy Permalänk
Medlem
Registrerad
Okt 2002

Ä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

http://blinkenshell.org - Gratis shellkonton. Inklusive webbhost med PHP & MySQL.
http://www.blinkenlights.se/ - En site om programmering och spelutveckling på svenska

Trädvy Permalänk
Medlem
Plats
R^n
Registrerad
Maj 2003

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.

:€

Trädvy Permalänk
Hedersmedlem
Plats
Stockholm
Registrerad
Dec 2002

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.

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

Trädvy Permalänk
Medlem
Plats
R^n
Registrerad
Maj 2003

Får felmeddelande "Missing name for redirect".

:€

Trädvy Permalänk
Medlem
Plats
Mölndal
Registrerad
Jul 2005
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

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

Trädvy Permalänk
Medlem
Plats
R^n
Registrerad
Maj 2003

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.

:€

Trädvy Permalänk
Hedersmedlem
Plats
Stockholm
Registrerad
Dec 2002
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.

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

Trädvy Permalänk
Medlem
Plats
R^n
Registrerad
Maj 2003

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?

:€

Trädvy Permalänk
Hedersmedlem
Plats
Stockholm
Registrerad
Dec 2002

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

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

Trädvy Permalänk
Medlem
Plats
Mölndal
Registrerad
Jul 2005
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!

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

Trädvy Permalänk
Medlem
Plats
R^n
Registrerad
Maj 2003
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.

:€

Trädvy Permalänk
Medlem
Plats
Mölndal
Registrerad
Jul 2005
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.

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