Komut dosyası çıktısının kendi kendine yeniden yönlendirmesinin tire eşdeğeri


9

Bash'te, o anda çalışan komut dosyasının gelecekteki tüm stdout çıktılarını yeniden yönlendirebilirsiniz . Örneğin bu komut dosyasıyla,

exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3

Bu, syslog ile sonuçlanır:

Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3

Ancak bu Bash'a özgüdür ve yönlendirme ile çıplak yürütme Dash'te çalışmıyor gibi görünüyor.

Syntax error: redirection unexpected

Dash'te veya muhtemelen her iki kabukta nasıl çalıştırabilirim?


Tam olarak neye ihtiyacınız olduğunu açıklar mısınız? >Tire ile yeniden yönlendirebilirsiniz . Başka bir şey istediğini anlıyorum ama ne olduğunu tam olarak anlayamıyorum.
terdon

@terdon Açıklamayı genişlettim.
Alex B

Yanıtlar:


6

Sadece şunları yapabilirsiniz:

{ commands
....
} | logger -t my_awesome_script

Bunu herhangi bir kabukla yapabilirsiniz.

Görünüşünü beğenmezseniz, komut dosyasının kendisini bir işlevde sarmasını sağlayın.

#!/bin/sh
run() if     [ "$run" != "$$" ] || return
      then   sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
             logger -t my-awesome-script
      fi
#script-body
run "$@" || do stuff

Bu son satır run ${1+"$@"} || do stuff, argümanların korunabilmesi için olmalıdır .
Adam Katz

@AdamKatz - iyi bir nokta, execpt ${1+"$@"}hiçbir şey yapmaz "$@" . Zaten başka sorunları da vardı.
mikeserv

"$@"""argüman olmadığında geçecek , argüman olmadığında ise ${1+"$@"}boş bir dize geçecektir. Bu, birçok program için çok önemlidir, çünkü ""boş bir argüman olarak ayrıştırılırken (alıntılanmamış) boş bir dize hiç bir argüman olarak yorumlanmayacaktır.
Adam Katz

@AdamKatz - çok eski bir Bourne kabuğu olabilir (ve ben dashböyle bir sistemde bulmayı beklemezdim ) , ancak başka türlü "$@"benzersizdir, çünkü sıfır değişkenli bir durum POSIX kabukları için boş bir argümanın yerine geçmez.
mikeserv

1
@AdamKatz - aslında eski bsh'de bile bir hataydı ve asla böyle çalışmamalıydı. Sonunda düzeltildi, ancak örneğin bir Solaris 10'da hala gerekli olup olmayacağını bilmiyorum. Haklısın $ * - dışavurumun aynı düzgün özelliklerini sergilemez - benzersizliği onky, her zaman bir şey olsa da, genişlemesinin değişken içeriğiyle ilgilidir "${@+is especially cool $@}" . Ama ${1+”$@"}sonuçta eski geçici çözümden pratik olarak çok farklı değil . Bir "${1+quoted" not quoted "quoted again}"
ksh93'niz

5

Proses ikamesi, adlandırılmış borularla kolayca simüle edilir.

mkfifo logger_input
logger -t my_awesome_script < logger_input &
exec > logger_input
echo 1
echo 2
echo 3

Aslında, adlandırılmış borular, /dev/fdişlem ikamesinin uygulanabileceği mekanizmalardan (diğeri ) biridir bash.


Bence en çok yönlü: Tee'yi çeşitli akışlara sorunsuz bir şekilde yönlendirmek için kullanabilirim. Sadece bir şey: bir komut dosyasının sonunda oluşturulan logger_input dosyasını silmeyi unutmayın.
lauhub

2

Bunun mümkün olduğunu düşünmüyorum dash. manSayfasından anlayabildiğim kadarıyla, işlem ikamesi için desteği yok.

Geçici bir çözüm olarak, mikserv'in önerisini deneyebilir veya her şeyi bir dosyaya yeniden yönlendirebilirsiniz ve ardından komut dosyanız bittikten sonra (muhtemelen bu bir komut dosyasındadır), o dosyanın içeriğini günlükçüye ekleyin:

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script

Aslında, işlem ikamesi - veya diğer mermilerin işlem ikamesi olarak adlandırdığı şey - diğer mermilerden daha kolaydır dash. Süreç ikamesi /dev/fd/[num], anonim bir borunun bağlantısına işaret eden bir argüman anlamına gelir . dashBurada, diğer kabukların çoğunda olduğu gibi geçici dosyalar oluşturmak yerine anonim kanallı belgeler yapar. Yani cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\nsadece işlevsel olarak eşdeğer değil, fd'yi kendiniz bile adlandırıyorsunuz. Yine de, diğer tarafa gitme konusunda iyi bir fikriniz var - yeni bir fd açmanız execve bunu okuyan bir işlemin arka planını yapmanız gerekir .
mikeserv

2
@mikeserv: Ne anlamda cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n"daha kolay" cat <(get output)?
ruakh

@mikeserv: Hatırlanması gereken birçok kural var; belki farketmeyeceğiniz kadar onlara alışmışsınızdır.
ruakh

@ruakh - iyi, tabii. < >kabuk yönlendirmeleri. temelde eğer bunlardan sadece iki tanesini yaparsanız, aşağıdaki satırlara da kazabilirsiniz. Ama evet, bir anlamı var - burada dokümanlarý seviyorum. Yine de hatırlamayı gerektirebilecek kadar çok şey, bence evrensel olarak çalıştıklarında daha kolay. Sonra yine birçok insanın diğer mermiler için fazla bir kullanımı yoktur ve bu yüzden onlar için hiçbir fark yaratmaz. Ben sadece onların arasında değilim.
mikeserv

1
@mikeserv: Sadece heredocs değil, aynı zamanda /dev/fd/3(bu kesin formda) ve boşluklara ne olduğuna dair ayrıntılar. . . ve bu nedenle, tüm bu yaklaşımın, tüm bileşenlere sahip diğer kabuklarda çalışmadığında, Dash'te hiç çalışmaması, genel yaklaşımın hatırlanması gereken özel bir kural olduğu anlamına gelir. ; (Bunlar kelimeler sever kesip Bu daha az kelime ile basitleştirilmiş İngilizce oluşturmak için girişimi hatırlatıyor devam , ama onlar gibi sadece-as-zor deyimleri görmezden üzerinde keep .)
ruakh
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.