Boru değişken atar


19

Basitlik için şunu yapmak istiyorum:

echo cart | assign spo;
echo $spo  

Çıktı: araba

Böyle bir assignuygulama var mı?

Bunu ikame kullanarak yapmanın tüm yollarının farkındayım.


Bunu neden değiştirmeden yapmak istiyorsun?
Thanatos

Yalnızca borularla yazarken ters Lehçe gösterim akışını seviyorum. Çok daha hızlı kodlama yapıyorum ve kod kalitesi / hızı o kadar önemli değil. Ayrıca ben Hella zincirin kısımlarını yorum yapmak kolaydır zincirleme olmadığında ve oldukça o anda geçerli çıkışını yankı silme kene vs.
MageProspero

Hata ayıklama kolaylığı konusunda endişeleriniz varsa, backticks komutunu bir dizi ayrı satıra koymayı düşünün. A=$( some | command | here )her biri ile some |, command |ve herekendi çizgisinde.
roaima

Yanıtlar:


11
echo cart | { IFS= read -r spo; printf '%s\n' "$spo"; }

Yalnızca bir satır echoçıktığı sposürece ( son satırsonu karakteri değişkeni olmadan çıktısını ) çalışır echo.

Her zaman şunları yapabilirsiniz:

assign() {
  eval "$1=\$(cat; echo .); $1=\${$1%.}"
}
assign spo < <(echo cart)

Aşağıdaki çözümler bashkomut dosyalarında çalışır, ancak komut bashisteminde çalışmaz :

shopt -s lastpipe
echo cat | assign spo

Veya:

shopt -s lastpipe
whatever | IFS= read -rd '' spo

whateverİlk NUL karaktere kadar olan çıktıları saklamak için ( bashdeğişkenler NUL karakterlerini yine de saklayamaz) $spo.

Veya:

shopt -s lastpipe
whatever | readarray -t spo

çıktısını depolamak için whateverde $spo dizi (dizi elemanı başına bir çizgi).


1
IFS=ve arasında boşluk olmamalı readmı?
caesarsol

Tüm son boru dolu. Ayrıca yan komut seti + m (ermmm veya -m) bir komut satırından gereklidir, çünkü son boru iş kontrolü etkinken çalışmaz.
MageProspero

17

Aşağıdaki gibi bir şey yapabilirsiniz bash:

echo cart | while read spo; do echo $spo; done

Ne yazık ki, "spo" değişkeni while - done döngüsü dışında var olmayacak. Eğer while döngüsü içinde ne istersen alabilirsin, bu işe yarayacak.

Aslında ATT ksh'da (pdksh veya mksh'de değil) veya muhteşem zsh'da neredeyse yazdıklarınızı neredeyse tamamen yapabilirsiniz:

% echo cart | read spo
% echo $spo
cart

Yani, başka bir çözüm ksh veya zsh kullanmak olacaktır.


1
Korn Shell'de (örneğin mksh) coprocesses kullanabilirsiniz : echo cart |& while read -p spo; do echo $spo; done(aslında kullanmak daha iyidir while IFS= read -p -r spo; do…)
mirabilos

2

Sorunu doğru anlarsam, stdout'u bir değişkene aktarmak istersiniz. En azından ben aradım ve burada sona erdi. Yani kaderimi paylaşanlar için:

spa=$(echo cart)

cartDeğişkeni atar $spa.


2
OP yerine kaçınmak istedikleri yerine ikame diyorlar.
Dmitry Grigoryev

Bu benim için yararlı oldu, ben sadece bir değişkene atamak gerekiyordu, ben oraya nasıl umurumda değildi!
Chris Marisic

1

Sadece mevcut boru akımı çıkışını kullanmak istiyorsanız cat.

echo cart | cat 

Komut zincirinize devam etmek istiyorsanız tee, çıkışı yankılamak için komutu kullanmayı deneyin .

echo cart | tee /dev/tty | xargs ls

Komutu kısaltmak için bir takma ad kullanabilirsiniz.

alias tout='tee /dev/tty'
echo cart | tout | xargs ls

Çıktıyı neden bir ovaya bağlamak istiyorsunuz cat?
roaima

1
@roaima Bazı komutlar bir uçbirim üzerinde çalıştıklarını ve bir boruya çıkış yaptıklarından farklı davrandıklarını fark eder. Özellikle, çizgileri geçerli ekran genişliğine kesebilirler. Çoğu komut için cat komutu gereksizdir.
BillThor

Ah tamam, şimdi göstermeye çalıştığın şeyi görüyorum. echo | catYapı beni attı.
roaima

1

İşte benim sorunun çözümü.

# assign will take last line of stdout and create an environment variable from it
# notes: a.) we avoid functions so that we can write to the current environment
#        b.) aliases don't take arguments, but we write this so that the "argument" appears
#            behind the alias, making it appear as though it is taking one, which in turn
#            becomes an actual argument into the temporary script T2.
# example: echo hello world | assign x && echo %x outputs "hello world"
alias assign="tail -1|tee _T1>/dev/null&&printf \"export \\\$1=\$(cat _T1)\nrm _T*\">_T2&&. _T2"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.