kzen.dev
  • Întrebări
  • Tag-uri
  • Utilizatori
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
 ldog
ldog
Question

Citiți valorile într-o coajă variabilă de la o conductă

Eu sunt încercarea de a obține bash pentru a prelucra datele de la intrarea standard, care devine, prin conducte, dar nu noroc. Ce vreau să spun este că nici una dintre următoarele lucrări:

echo "hello world" | test=($(< /dev/stdin)); echo test=$test
test=

echo "hello world" | read test; echo test=$test
test=

echo "hello world" | test=`cat`; echo test=$test
test=

unde vreau ieșire pentru a fi test=salutare lume. Am'am încercat să - "" ghilimele `"$test" asta nu't de lucru, fie.

193 2010-04-30T17:51:55+00:00 15
 codeforester
codeforester
Întrebarea editată 25 august 2018 в 4:12
Programare
pipe
linux
bash
Solution / Answer
 yardena
yardena
21 iulie 2011 в 4:19
2011-07-21T16:19:55+00:00
Mai mult
Sursă
Editează
#10395239

Utilizarea

IFS= read var << EOF
$(foo)
EOF

Ai poate truc citit în acceptarea dintr-o țeavă de genul asta:

echo "hello world" | { read test; echo test=$test; }

sau chiar scrie o funcție astfel:

read_from_pipe() { read "$@" <&0; }

Dar nu's nici un punct - sarcini variabile nu poate dura! O conductă poate da naștere la o subshell, unde mediul este moștenit prin valoare, nu prin referință. Acesta este motivul pentru "citit" nu't deranjez cu intrare dintr-o țeavă - l's nedefinit.

FYI, http://www.etalabs.net/sh_tricks.html este un puturos de colectare a cruft necesar pentru a lupta împotriva ciudățenii și incompatibilități de bourne scoici, sh.

 fedorqui
fedorqui
Răspuns editat 28 aprilie 2014 в 9:19
159
0
 Nick
Nick
1 mai 2010 в 2:48
2010-05-01T02:48:36+00:00
Mai mult
Sursă
Editează
#10395238

dacă doriți să citiți într-o mulțime de date și de a lucra pe fiecare linie separat, ai putea folosi ceva de genul asta:

cat myFile | while read x ; do echo $x ; done

dacă doriți să împartă linii în mai multe cuvinte, puteți folosi mai multe variabile în loc de x, astfel:

cat myFile | while read x y ; do echo $y $x ; done

alternativ:

while read x y ; do echo $y $x ; done < myFile

Dar de îndată ce începi să vrei să faci ceva cu adevărat inteligent cu acest fel de lucru're mai bine merge pentru un limbaj de scripting ca perl unde ai putea încerca ceva de genul asta:

perl -ane 'print "$F[0]\n"' < myFile

Nu's destul de curbă de învățare abruptă cu perl (sau cred că oricare dintre aceste limbi) dar'll găsi mult mai ușor pe termen lung, dacă vrei să faci ceva, dar simplu de script-uri. Am'd recomanda Perl carte de Bucate și, desigur, Perl Limbaj de Programare de Larry Wall et al.

105
0
Steven Penny
Steven Penny
19 iunie 2012 в 11:47
2012-06-19T11:47:05+00:00
Mai mult
Sursă
Editează
#10395240

Aceasta este o altă opțiune

$ read test < <(echo hello world)

$ echo $test
hello world
Steven Penny
Steven Penny
Răspuns editat 30 octombrie 2014 в 3:12
39
0
Dennis Williamson
Dennis Williamson
30 aprilie 2010 в 6:08
2010-04-30T18:08:10+00:00
Mai mult
Sursă
Editează
#10395237

a "citi" a câștigat't citit dintr-o țeavă (sau, eventual, rezultatul este pierdut deoarece conducta creează un subshell). Cu toate acestea, puteți utiliza o aici șir în Bash:

$ read a b c <<< $(echo 1 2 3)
$ echo $a $b $c
1 2 3

Dar vezi @chepner's a răspunde pentru informații despre lastpipe`.

Dennis Williamson
Dennis Williamson
Răspuns editat 30 aprilie 2019 в 3:53
39
0
 djanowski
djanowski
4 octombrie 2012 в 1:52
2012-10-04T13:52:32+00:00
Mai mult
Sursă
Editează
#10395243

Am'm expert în Bash, dar mă întreb de ce acest lucru nu't fost propuse:

stdin=$(cat)

echo "$stdin"

-O linie dovada că funcționează pentru mine:

$ fortune | eval 'stdin=$(cat); echo "$stdin"'
 djanowski
djanowski
Răspuns editat 4 octombrie 2012 в 2:07
30
0
 chepner
chepner
2 octombrie 2013 в 5:04
2013-10-02T17:04:42+00:00
Mai mult
Sursă
Editează
#10395245

bash 4.2 introduce lastpipe opțiune, care permite cod pentru a lucra ca scris, prin executarea ultimei comenzi într-o conductă în shell-ul curent, mai degrabă decât un subshell.

shopt -s lastpipe
echo "hello world" | read test; echo test=$test
24
0
 mob
mob
30 aprilie 2010 в 5:58
2010-04-30T17:58:36+00:00
Mai mult
Sursă
Editează
#10395235

Sintaxa pentru o implicită țeavă dintr-o coajă de comandă într-un bash variabilă este

var=$(command)

sau

var=`command`

În exemplele tale, ești de conducte date de la o declarație de atribuire, care nu se așteaptă la intrare.

13
0
 jbuhacoff
jbuhacoff
2 august 2013 в 5:06
2013-08-02T05:06:08+00:00
Mai mult
Sursă
Editează
#10395244

Prima încercare a fost destul de aproape. Această modificare ar trebui să funcționeze:

echo "hello world" | { test=$(< /dev/stdin); echo "test=$test"; };

și de ieșire este:

test=salut lume

Ai nevoie de aparat dentar după conductei să anexați misiune pentru a testa și de ecou.

Fără bretele, misiunea de a testa (după conductei) este într-o coajă, și ecoul "test=$test" este separat într-o coajă care nu't știu despre tema asta. Ca's de ce ai "test=" la ieșire în loc de "test=salut lume".

6
0
 Jaleks
Jaleks
21 iulie 2016 в 3:42
2016-07-21T15:42:57+00:00
Mai mult
Sursă
Editează
#10395248

În ochii mei cel mai bun mod de a citi de la intrarea standard în bash este următorul, care, de asemenea, vă permite să lucreze pe liniile înainte de intrare se termină:

while read LINE; do
    echo $LINE
done < /dev/stdin
6
0
 hd-quadrat
hd-quadrat
8 octombrie 2016 в 9:35
2016-10-08T21:35:30+00:00
Mai mult
Sursă
Editează
#10395249

Pentru că nu se încadrează pentru ea, aș dori să picătură o notă. Am gasit acest thread, pentru că trebuie să rescrie un vechi sh script pentru a fi compatibil POSIX. Acest lucru înseamnă, practic, să eludeze țeavă/subshell problema introdus de POSIX prin rescrierea codului astfel:

some_command | read a b c

în:

read a b c << EOF
$(some_command)
EOF

Și ca acest cod:

some_command |
while read a b c; do
    # something
done

în:

while read a b c; do
    # something
done << EOF
$(some_command)
EOF

Dar acesta din urmă nu se comporta la fel pe gol de intrare. Cu vechea notație buclă în timp ce este introdus în gol de intrare, dar în POSIX notație este! Cred că's, datorită newline înainte de EOF, care nu poate fi omis. La POSIX cod care se comportă mai mult ca vechea notație se pare ca acest lucru:

while read a b c; do
    case $a in ("") break; esac
    # something
done << EOF
$(some_command)
EOF

În cele mai multe cazuri, acest lucru ar trebui să fie destul de bun. Dar, din păcate, acest lucru încă nu se comportă exact ca vechea notație dacă some_command imprimă o linie goală. În vechea notație în timp ce corpul este executat și în POSIX notație ne rupe în fața corpului.

O abordare pentru a rezolva acest lucru ar putea arata astfel:

while read a b c; do
    case $a in ("something_guaranteed_not_to_be_printed_by_some_command") break; esac
    # something
done << EOF
$(some_command)
echo "something_guaranteed_not_to_be_printed_by_some_command"
EOF
 hd-quadrat
hd-quadrat
Răspuns editat 9 octombrie 2016 в 9:20
5
0
 bta
bta
30 aprilie 2010 в 5:54
2010-04-30T17:54:36+00:00
Mai mult
Sursă
Editează
#10395234

Conducte de ceva într-o expresie care implică o însărcinare nu't se comporte așa.

În schimb, încercați:

test=$(echo "hello world"); echo test=$test
3
0
 Jahid
Jahid
9 iulie 2015 в 6:54
2015-07-09T18:54:11+00:00
Mai mult
Sursă
Editează
#10395246

Următorul cod:

echo "hello world" | ( test=($(< /dev/stdin)); echo test=$test )

va lucra, dar se va deschide un alt nou sub-shell după conductei, în cazul în care

echo "hello world" | { test=($(< /dev/stdin)); echo test=$test; }

a câștigat't.


Am avut pentru a dezactiva control de locuri de muncă pentru a face uz de chepnars' metoda (am fost de a rula această comandă din terminal):

set +m;shopt -s lastpipe
echo "hello world" | read test; echo test=$test
echo "hello world" | test="$(</dev/stdin)"; echo test=$test

Bash Manual scrie:

lastpipe

Dacă este setat, și de locuri de muncă de control nu este activ, shell-ul se execută ultima comandă de o conductă să nu fie executat în fundal în shell-ul curent mediu.

Notă: lucrare de control este dezactivat în mod implicit într-un mod non-interactiv coajă și, astfel, nu't nevoie de set +m` în interiorul unui script.

 Community
Community
Răspuns editat 23 mai 2017 в 12:18
2
0
Mathieu J.
Mathieu J.
10 iulie 2012 в 2:19
2012-07-10T02:19:51+00:00
Mai mult
Sursă
Editează
#10395242

Cred că ai fost încercarea de a scrie un script shell care ar putea să ia de intrare de la stdin. dar în timp ce sunteți încercarea de a face inline, te-ai pierdut încercarea de a crea acel test= variabilă. Cred că nu prea are sens să-l facă inline, și că's de ce nu funcționează așa cum vă așteptați.

Am fost încercarea de a reduce

$( ... | head -n $X | tail -n 1 )

pentru a obține o anumită linie din diverse intrare. așa am putut de tip...

cat program_file.c | line 34

deci am nevoie de un mic program shell capabil de a citi de la intrarea standard. cum faci tu.

22:14 ~ $ cat ~/bin/line 
#!/bin/sh

if [ $# -ne 1 ]; then echo enter a line number to display; exit; fi
cat | head -n $1 | tail -n 1
22:16 ~ $ 

acolo te duci.

1
0
 Seff
Seff
5 mai 2019 в 6:04
2019-05-05T06:04:05+00:00
Mai mult
Sursă
Editează
#10395250

Un script inteligente care pot citi date de pe ȚEAVĂ și argumente în linia de comandă:

#!/bin/bash
if [[ -p /proc/self/fd/0 ]]
    then
    PIPE=$(cat -)
    echo "PIPE=$PIPE"
fi
echo "ARGS=$@"

Ieșire:

$ bash test arg1 arg2
ARGS=arg1 arg2

$ echo pipe_data1 | bash test arg1 arg2
PIPE=pipe_data1
ARGS=arg1 arg2

Explicație: atunci Când un script primește date prin țeavă, apoi stdin /proc/auto/fd/0 va fi o legătură simbolică la o conductă.

/proc/self/fd/0 -> pipe:[155938]

Dacă nu, acesta va fi punctul de la actualul terminal:

/proc/self/fd/0 -> /dev/pts/5

Bash dacă -p opțiune poate verifica că este o conductă sau nu.

pisica citește de la intrarea standard`.

Dacă vom folosi pisica, atunci când nu există nici o stdin, se va aștepta pentru totdeauna, de aceea am pus-o în interiorul "dacă" starea.

1
0
 bingles
bingles
21 august 2015 в 11:44
2015-08-21T11:44:50+00:00
Mai mult
Sursă
Editează
#10395247

Ce zici de asta:

echo "hello world" | echo test=$(cat)
-1
0
Comunități asemănătoare 1
DevOps - comunitatea Română
DevOps - comunitatea Română
15 utilizatori
Vorbim despre Kubernetes, CI/CD, Linux, docker, monitorizare, Cloud services, Prometheus, network și orice alte teme legate de administrarea serverelor.
Deschide telegram
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
Utilizatori
Toate
Nou
Populare
1
工藤 芳則
Înregistrat 6 zile în urmă
2
Ирина Беляева
Înregistrat 1 săptămână în urmă
3
Darya Arsenyeva
Înregistrat 1 săptămână în urmă
4
anyta nuam-nuam (LapuSiK)
Înregistrat 1 săptămână în urmă
5
Shuhratjon Imomkulov
Înregistrat 1 săptămână în urmă
DE
ES
ID
JA
KO
RO
RU
TR
ZH
© kzen.dev 2023
Sursă
stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire