Vra

Kan iemand verduidelik hierdie gedrag?Hardloop:

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

resultate in niks om output, terwyl:

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

produseer die verwagte uitset:

hello
world

Moet nie die pyp nie in een stap wat die herleiding te toets.die lêer het in die tweede voorbeeld?Ek het probeer om die dieselfde kode met beide die dash en bash skulpe en het dieselfde gedrag van beide van hulle.

Was dit nuttig?

Oplossing

In 'n onlangse toevoeging tot bash is die lastpipe opsie, wat die laaste opdrag kan in 'n pypleiding te voer in die huidige dop, nie 'n subskil, wanneer werk beheer is gedeaktiveer.

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

sal inderdaad uitset

hello
world

Ander wenke

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

produseer geen uitset want pyplyne loop elk van hul komponente binne'n subshell.Subshells erf afskrifte van die ouer shell se veranderlikes, eerder as deel van hulle.Probeer om hierdie:

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

Die hakies definieer'n streek van die kode wat loop in'n subshell, en $foo behou sy oorspronklike waarde na verander binne-in hulle.

Nou probeer om hierdie:

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

Die draadjies is suiwer vir die groepering, geen subshell is geskep, en die $foo verander binne-in die draadjies is die dieselfde $foo verander buite hulle.

Nou probeer om hierdie:

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

Binne-in die draadjies, die lees ingeboude skep $var1 en $var2 behoorlik en jy kan sien dat hulle kry eggo.Buite die draadjies, het hulle nie bestaan nie meer nie.Al die kode in die draadjies is loop in'n subshell want dit is een komponent van'n pyplyn.

Jy kan sit arbitrêre bedrae van die kode tussen draadjies, sodat jy kan gebruik om hierdie pype-in-'n-blok konstruksie wanneer jy nodig het om'n blok van shell script wat ontleed die uitset van iets anders.

Dit is reeds korrek beantwoord word, maar die oplossing is nog nie verklaar. Gebruik KSH, nie bash. Vergelyk:

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

Aan:

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

KSH is 'n uitstekende program dop as gevolg van min niceties soos hierdie. (Bash is die beter interaktiewe dop, in my opinie.)

read var1 var2 < <(echo "hello world")

Die post behoorlik beantwoord nie, maar ek wil graag 'n alternatiewe een sak wat dalk van 'n paar gebruik kan bied.

Vir die toeken van die ruimte geskei waardes van eggo (of stdout vir die saak) om veranderlikes dop, kan jy oorweeg om dop skikkings:

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

In hierdie voorbeeld var is 'n skikking en die inhoud kan verkry word met behulp van die konstruk $ {var [indeks]}, waar indeks is die skikking indeks (begin met 0).

Die manier wat jy kan soveel parameters het as jy na die relevante reeks indeks wil opgedra.

My siening oor hierdie kwessie (met behulp van Bash):

read var1 var2 <<< "hello world"
echo $var1 $var2

Allright, gedink ek dit uit!

Dit is 'n harde fout om te vang, maar die gevolg van die manier pype word hanteer deur die dop. Elke element van 'n pypleiding loop in 'n afsonderlike proses. Wanneer die lees opdrag stelle VAR1 en VAR2, is stel hulle dit sy eie subskil, nie die ouer dop. So wanneer die subskil uitgange, die waardes van var1 en VAR2 verlore. Jy kan egter probeer doen

var1=$(echo "Hello")
echo var1

wat gee die verwagte antwoord. Ongelukkig is hierdie net werke vir enkele veranderlikes, jy kan nie baie op 'n slag te stel. Ten einde meerdere veranderlikes gestel op 'n slag moet jy óf lees in een veranderlike en kap dit in verskeie veranderlikes of so iets gebruik:

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

Terwyl ek erken dit is nie so elegant soos die gebruik van 'n pyp, dit werk. Natuurlik moet jy in gedagte hou dat lees veronderstel was om te lees van lêers in veranderlikes hou, so maak dit lees van standaard insette moet 'n bietjie moeiliker wees.

Dit is omdat die pyp weergawe is die skep van 'n subskil, wat die veranderlike in sy plaaslike ruimte wat dan vernietig lui wanneer die subskil uitgange.

Voer die opdrag

$ echo $$;cat | read a
10637

en gebruik pstree p om te kyk na die verloop prosesse, sal jy sien 'n ekstra dop hang af van jou belangrikste dop.

    |                       |-bash(10637)-+-bash(10786)
    |                       |             `-cat(10785)

Drie:

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

Die probleem, soos verskeie mense het gesê, is dat var1 en VAR2 geskep in 'n subskil omgewing wat vernietig wanneer dit subskil uitgange. Bogenoemde vermy die vernietiging van die subskil totdat die gevolg is echo'd. Nog 'n oplossing is:

result=`echo "hello world"`
read var1 var2 <<EOF
$result
EOF
echo $var1
echo $var2
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top