Shell script bemenet átirányítása furcsaságokat

szavazat
16

Tud valaki magyarázni ezt a viselkedést? Futás:

#!/bin/sh
echo hello world | read var1 var2
echo $var1
echo $var2

eredményük nem pedig ouput, míg:

#!/bin/sh
echo hello world > test.file
read var1 var2 < test.file
echo $var1
echo $var2

az elvárt kimenet:

hello
world

Nem kellene a cső itt egy lépésben, amit a átirányítás test.file tette a második példában? Megpróbáltam ugyanazt a kódot mind a kötőjel és bash héj és kapott ugyanazt a viselkedést mind a ketten.

A kérdést 05/08/2008 20:26
a forrás felhasználó
Más nyelveken...                            


9 válasz

szavazat
11
#!/bin/sh
echo "hello world" | read var1 var2
echo $var1
echo $var2

nem generál kimenő mert csővezetékek fut minden alkatrészük belül alburok. Subshells öröklik példányban a szülő shell változók, hanem megosztva. Próbáld ezt:

#!/bin/sh
foo="contents of shell variable foo"
echo $foo
(
    echo $foo
    foo="foo contents modified"
    echo $foo
)
echo $foo

A zárójelben meg egy régió kód fusson egy alburok, és a $ ize megtartja eredeti érték, miután a módosított bennük.

Most próbáld ezt:

#!/bin/sh
foo="contents of shell variable foo"
echo $foo
{
    echo $foo
    foo="foo contents modified"
    echo $foo
}
echo $foo

A merevítők pusztán csoportosulás nem alburok létre, és az $ ize módosított belül a zárójelek azonos $ ize módosított kívül.

Most próbáld ezt:

#!/bin/sh
echo "hello world" | {
    read var1 var2
    echo $var1
    echo $var2
}
echo $var1
echo $var2

Bent a zárójelek között, az olvasási beépített teremt $ var1 és $ var2 megfelelően, és láthatjuk, hogy kap visszhangzott. Kívül a zárójelek között, azok nem léteznek többé. Minden kódot a nadrágtartó már fut egy alburok mert ez az egyik eleme egy gázvezeték .

Tudod, hogy tetszőleges mennyiségű kód közötti nadrágtartó, így használhatja ezt a csővezeték-be-a-blokk építése, amikor meg kell futtatni egy blokk shell script, ami értelmezi a kimenet valami mást.

Válaszolt 19/09/2008 03:20
a forrás felhasználó

szavazat
9

Ezt már válaszolt helyesen, de a megoldás még nem említették még. Használja ksh, bash nem. Összehasonlítás:

$ echo 'echo "hello world" | read var1 var2
echo $var1
echo $var2' | bash -s

Nak nek:

$ echo 'echo "hello world" | read var1 var2
echo $var1
echo $var2' | ksh -s
hello
world

ksh egy kiváló programozási shell miatt kis apró örömök, mint ez. (Bash a jobb interaktív shell, véleményem szerint.)

Válaszolt 15/08/2008 16:52
a forrás felhasználó

szavazat
8

Egy nemrégiben kívül bashaz lastpipea lehetőség, amely lehetővé teszi, hogy az utolsó parancsot egy gázvezeték fut az aktuális shell, nem alburok, ha a feladat ki van kapcsolva.

#!/bin/bash
set +m      # Deactiveate job control
shopt -s lastpipe
echo "hello world" | read var1 var2
echo $var1
echo $var2

lesz valóban kimenet

hello
world
Válaszolt 26/07/2012 13:10
a forrás felhasználó

szavazat
8
read var1 var2 < <(echo "hello world")
Válaszolt 17/09/2008 01:17
a forrás felhasználó

szavazat
5

Rendben, rájöttem!

Ez egy nehéz elkapni bug eredménye, hanem az út csövek kezeli a héj. Minden eleme egy gázvezeték fut egy külön folyamat. Amikor az olvasási parancs készlet var1 és var2, ez különbözteti meg őket, hogy a saját alburok, nem a szülő shell. Tehát amikor a alhéj kilép, az értékek var1 és var2 elvesznek. Akkor azonban, próbálkozzon

var1=$(echo "Hello")
echo var1

amely visszaadja a várt választ. Sajnos ez csak az egyetlen változó, akkor nem lehet beállítani sok egy időben. Annak érdekében, hogy több változó egy időben akkor vagy olvassa be egy változó, és vágja fel több változó vagy használja valami ilyesmi:

set -- $(echo "Hello World")
var1="$1" var2="$2"
echo $var1
echo $var2

Bár bevallom, hogy nem olyan elegáns, mint egy cső, akkor működik. Természetesen meg kell szem előtt tartani, hogy olvassa el kellett volna olvasni a fájlokat változókat, ezért ezzel a szabványos bemenetről olvas kell egy kicsit nehezebb.

Válaszolt 05/08/2008 21:09
a forrás felhasználó

szavazat
4

Az én veszi ezt a kérdést (a Bash):

read var1 var2 <<< "hello world"
echo $var1 $var2
Válaszolt 04/03/2009 10:52
a forrás felhasználó

szavazat
4

A bejegyzést megfelelően válaszol, de szeretném, hogy alternatívát kínáljon egy óceánjáró, hogy talán lehet valami használatra.

Sorolásának szóközzel elválasztott értékeket echo (vagy stdoutra ami azt illeti), hogy shell változók, hogy mérlegelje shell tömbök:

$ var=( $( echo 'hello world' ) )
$ echo ${var[0]}
hello
$ echo ${var[1]}
world

Ebben a példában a var tömb, és a tartalom lehet hozzáférni a konstrukció $ {var [index]}, ahol index tömbindexként (kezdődik 0).

Így lehet, hogy annyi paramétert, amennyit akar rendelni a megfelelő index.

Válaszolt 14/09/2008 18:00
a forrás felhasználó

szavazat
4

Azért, mert a cső változat létrehozása alburok, amely beolvassa a változót a lokális tér, amely aztán elpusztul, ha a subshell kilép.

Ezt a parancsot

$ echo $$;cat | read a
10637

és használja pstree -p hogy nézd meg a futó folyamatokat, akkor megjelenik egy extra shell lóg le a fő shell.

    |                       |-bash(10637)-+-bash(10786)
    |                       |             `-cat(10785)
Válaszolt 05/08/2008 21:00
a forrás felhasználó

szavazat
3

Próbáld ki:

echo "hello world" | (read var1 var2 ; echo $var1 ; echo $var2 )

A probléma, mivel több ember kijelentette, hogy var1 és var2 jönnek létre alburok környezetben elpusztul, amikor a alburok kilép. A fenti meghiúsítja elpusztítja a alhéj amíg az eredmény már echo'd. Egy másik megoldás:

result=`echo "hello world"`
read var1 var2 <<EOF
$result
EOF
echo $var1
echo $var2
Válaszolt 17/09/2008 03:15
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more