Dizeyi stdin'e gönder


158

Bunu etkili bir şekilde bash'da yapmanın bir yolu var mı:

/my/bash/script < echo 'This string will be sent to stdin.'

Yankıdan çıktıyı şu şekilde aktarabileceğimin farkındayım:

echo 'This string will be piped to stdin.' | /my/bash/script

1
Etkili olarak ne demek istiyorsun , neden boru bunu yapmanın bir yolu değil?
Andy

Listelediğiniz bu komutların her ikisi de aynı şeyi yapmalıdır. Ne problemin var?
Flimzy

5
@Flimzy: beklendiği gibi afaik, ilki bu isimli bir dosyayı açmaya çalışacağım, işe yaramazecho
Andy

Ah doğru. İkinci formda sorun nedir?
Flimzy

2
@Flimzy: ayrıca, >yeniden yönlendirme formu fd 0(stdin) olarak bir dosya tanımlayıcısını açarken, |açılışlar bir alt işlemi başlatır ve stdout'unu (fd 1) diğer sürecin stdin'ine ekler. Bu gerçeğin önemsiz sonuçları olabilir (ortam değişkenlerini paylaşmayı düşünün?)
sehe

Yanıtlar:


262

Tek satır kullanabilirsiniz heredoc

cat <<< "This is coming from the stdin"

yukarıdaki ile aynı

cat <<EOF
This is coming from the stdin
EOF

ya da çıktıyı bir komuttan,

diff <(ls /bin) <(ls /usr/bin)

ya da şöyle okuyabilirsin

while read line
do
   echo =$line=
done < some_file

ya da sadece

echo something | read param

Ve bu şekilde ikili değerler nasıl girilir? Boruyu kullanmadan (aşağıdaki gibi bunun boru ile yapılabilir biliyorum: echo -e "\x01\x02..." | ./script)
cprcrack

Başka türlü yazmayı seviyorum: <<< "Bu stdin'den geliyor" perl ..., bu şekilde borunun sol tarafına benziyor.
Pirolistik

@Pyrolistik evet! Özellikle bir komut satırından perl oneliner üzerinde ustalaşırken kullanışlıdır - perl argümanlarının imleçle fazla geriye doğru hareket etmesine gerek kalmadan kolayca düzenlenmesi. :)
jm666

@ jm666 üzgün şey dün öğrendiğimde bir bash takma adı kullanırsanız, sadece command_alias <<< "stdin string" formunu kullanırsınız, aksi halde komut bulunamadı diyecektir
Pyrolistics

@ jm666 Hakkında daha fazla bilgi edinebileceğim bir yer var <<<mı? Daha önce hiç görmediğimi itiraf etmekten utanıyorum ve tamamen gizem duyuyorum. Google'ı bunun için denedim, ancak sonuçlarım ilgisiz.
wpcarro

66

Yakındın

/my/bash/script <<< 'This string will be sent to stdin.'

Çok satırlı giriş için, bu dokümanlar uygundur:

/my/bash/script <<STDIN -o other --options
line 1
line 2
STDIN

Düzenle Yorumlara:

İkili girdi elde etmek için,

xxd -r -p <<BINARY | iconv -f UCS-4BE -t UTF-8 | /my/bash/script
0000 79c1 0000 306f 0000 3061 0000 3093 0000 3077 0000 3093 0000 304b 0000 3093 0000 3077 0000 3093 0000 306a 0000 8a71 0000 306b 0000 30ca 0000 30f3 0000 30bb
0000 30f3 0000 30b9 0000 3092 0000 7ffb 0000 8a33 0000 3059 0000 308b 0000 3053 0000 3068 0000 304c 0000 3067 0000 304d 0000 000a
BINARY

Eğer yerine ise catiçin /my/bash/script(ya da aslında son borusunu damla), bu baskılar:

私はちんぷんかんぷんな話にナンセンスを翻訳することができ

Ya da, biraz daha geeky bir şey istiyorsanız:

0000000: 0000 0000 bef9 0e3c 59f8 8e3c 0a71 d63c  .......<Y..<.q.<
0000010: c6f2 0e3d 3eaa 323d 3a5e 563d 090e 7a3d  ...=>.2=:^V=..z=
0000020: 7bdc 8e3d 2aaf a03d b67e b23d c74a c43d  {..=*..=.~.=.J.=
0000030: 0513 d63d 16d7 e73d a296 f93d a8a8 053e  ...=...=...=...>
0000040: 6583 0e3e 5a5b 173e 5b30 203e 3d02 293e  e..>Z[.>[0 >=.)>
0000050: d4d0 313e f39b 3a3e 6f63 433e 1c27 4c3e  ..1>..:>ocC>.'L>
0000060: cde6 543e 59a2 5d3e 9259 663e 4d0c 6f3e  ..T>Y.]>.Yf>M.o>
0000070: 60ba 773e cf31 803e ee83 843e 78d3 883e  `.w>.1.>...>x..>
0000080: 5720 8d3e 766a 913e beb1 953e 1cf6 993e  W .>vj.>...>...>
0000090: 7a37 9e3e c275 a23e dfb0 a63e bce8 aa3e  z7.>.u.>...>...>
00000a0: 441d af3e 624e b33e 017c b73e 0ca6 bb3e  D..>bN.>.|.>...>
00000b0: 6fcc bf3e 15ef c33e e90d c83e d728 cc3e  o..>...>...>.(.>
00000c0: c93f d03e ac52 d43e 6c61 d83e f36b dc3e  .?.>.R.>la.>.k.>
00000d0: 2f72 e03e 0a74 e43e 7171 e83e 506a ec3e  /r.>.t.>qq.>Pj.>
00000e0: 945e f03e 274e f43e f738 f83e f11e fc3e  .^.>'N.>.8.>...>
00000f0: 0000 003f 09ee 013f 89d9 033f 77c2 053f  ...?...?...?w..?
0000100: caa8 073f 788c 093f 776d 0b3f be4b 0d3f  ...?x..?wm.?.K.?
0000110: 4427 0f3f 0000 113f e8d5 123f f3a8 143f  D'.?...?...?...?
0000120: 1879 163f 4e46 183f 8d10 1a3f cad7 1b3f  .y.?NF.?...?...?
0000130: fe9b 1d3f 1f5d 1f3f 241b 213f 06d6 223f  ...?.].?$.!?.."?
0000140: bb8d 243f 3a42 263f 7cf3 273f 78a1 293f  ..$?:B&?|.'?x.)?
0000150: 254c 2b3f 7bf3 2c3f 7297 2e3f 0138 303f  %L+?{.,?r..?.80?
0000160: 22d5 313f ca6e 333f                      ".1?.n3?

4 baytlık ikili şamandıralarda ilk 90 derecenin sinüsü olan


Ve bu şekilde ikili değerler nasıl girilir?
cprcrack

Bana kalırsa doğru xxd -r(veya odBURADA belgeyi süzmek için)
sehe

Bir örnekle açıklayabilir misiniz? Bunu başaramadım.
cprcrack

1
düzenlenen cevaba bakınız. Mesele, betiğinize ham ikili verileri dahil etmemek, bunun yerine
xxd

Bunun ne anlamı var: "/ my / bash / script <<< 'Bu dize stdin'e gönderilecek." "Doğrudan şunu söyleyebilirsiniz:" / my / bash / script' Bu dize stdin'e gönderilecektir. ""?
Baiyan Huang

2

Ayrıca kullanabilirsiniz readböyle

echo "enter your name"
read name
echo $name

2

Çözüm

Bir işlemde (1) stdout çıkışı oluşturmak ( echo '…'ve) ve (2) bu çıkışı başka bir işlemin stdin girişine, ancak (3) bash boru mekanizması kullanmadan yönlendirmek istiyorsunuz . İşte üç koşulun tümüne uyan bir çözüm:

/my/bash/script < <(echo 'This string will be sent to stdin.')

<Standart girdi için normal giriş yönlendirilişi. The <(…)bash işlem ikamesi. Kabaca /dev/fd/…, ikame komutunun çıktısına sahip bir dosya oluşturur ve bu dosya adını yerine geçirir, <(…)örneğin burada sonuçlanır script < /dev/fd/123. Ayrıntılar için bu cevaba bakın

Diğer çözümlerle karşılaştırma

  • Stdin'e gönderilen tek satırlı bir yorumlu metin script <<< 'string', diğer komutların çıktısını değil, yalnızca statik dizeleri göndermeye izin verir.

  • Sadece süreç ikamesi, içinde olduğu gibi diff <(ls /bin) <(ls /usr/bin), stdin'e hiçbir şey göndermez. Bunun yerine, işlem çıktısı, örneğin arka plana eşdeğer olarak arka planda oluşturulan dosyaların içeriği olarak geçirilir diff /dev/fd/10 /dev/fd/11. Bu komutta diffstdin'den girdi almaz.

Kullanım örnekleri

Bunu beğendim, boru mekanizmasının aksine, < <(…) komutu ve ardından tüm girdiyi komut satır seçeneklerinden girdi standardı olarak koymaya izin verir.

Bununla birlikte, komut satırı estetiğinin ötesinde, bir boru mekanizmasının kullanılamadığı bazı durumlar vardır. Örneğin, belirli bir komutun bu örnektesshpass olduğu gibi başka bir komuta argüman olarak sağlanması gerektiğinde .


İlginç bir alternatif. Bunun aksine POSIX uyumlu <<<mu?
Tüm İşçiler

0
cat | /my/bash/script

Bu giriş geçmişe kaydedilmeden veya görünür olmadan bir programa birden çok satır yazılmasını sağlar ps. Yazmayı bitirdiğinizde sadece Ctrl + C tuşlarına basın cat.


-1

takma adlar borulu stdin'i işleyebilir ve işleyemez ...

Burada 3 satır çıktı oluşturuyoruz

$ echo -e "line 1\nline 2\nline 3"
line 1
line 2
line 3

Daha sonra, hepsini tek bir satıra koymak için sed komutunun çıkışına yönlendiriyoruz

$ echo -e "line 1\nline 2\nline 3" |  sed -e ":a;N;\$!ba ;s?\n? ?g"
line 1 line 2 line 3

Aynı sed komutunun takma adını tanımlarsak

$ alias oline='sed -e ":a;N;\$!ba ;s?\n? ?g"'

Çıktıyı takma adın kenarına bağlayabiliriz ve tamamen aynı şekilde davranır

$ echo -e "line 1\nline 2\nline 3" |  oline
line 1 line 2 line 3

Diğer adı bir işlev olarak tanımlamaya çalıştığımızda sorun ortaya çıkıyor

$ alias oline='function _oline(){ sed -e ":a;N;\$!ba ;s?\n? ?g";}_oline'

Takma adı bir funstion olarak tanımlamak boruyu kırar

$ echo -e "line 1\nline 2\nline 3" |  oline
>

İlk olarak, bu soruya cevap vermiyor - belki yanlış soruyu cevapladınız? İkincisi, neden bir takma adın içinde bir fonksiyon tanımladınız? Sadece yapmalısın function oline() { sed -e ":a;N;\$!ba ;s?\n? ?g"; }. Üçüncüsü, bu sed awk ile çok daha anlaşılır olurdu:awk -F '\n' 'ORS=" " { print } END { printf "\n"}'
Leonardo Dagnino
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.