Çıktısının bir terminale gittiğini düşünerek bir komutu nasıl kandırabilirim?


38

Çıkışı bir terminale giderken davranışını değiştiren bir komut verildiğinde (örneğin, renkli çıktı üretir), bu davranış değiştirilen davranışı koruyarak bir boru hattında nasıl yönlendirilebilir? Bunun için bilmediğim bir yardımcı program olmalı.

Bazı komutların, grep --color=alwaysdavranışı zorlamak için seçenek bayrakları vardır, ancak soru, yalnızca çıktı dosyası tanımlayıcısını sınamaya dayanan programlar üzerinde nasıl çalışılacağıdır.

Önemli olursa, benim kabuğum bashLinux'ta.


Komutun çıkış dosya tanımlayıcısını nasıl test ettiğini ve bir şekilde bir çıkış terminalinden görülebilecek sonuçlarla tutarlı sonuçlar döndürdüğünü bilmek zorundasınız.
Andrew Henle,

Yanıtlar:


21

İhtiyacınız olanı kullanarak alabilirsiniz unbuffer.

unbufferbir tcl/ expectscript. İsterseniz kaynağa bakın. Ayrıca erkekte CAVEATS bölümüne de dikkat edin.

Ayrıca, şu gibi takma adları çalıştırmadığını unutmayın:

alias ls='ls --color=auto'

biri Stéphane Chazelas'ın belirttiği gibi bir numara eklemediği sürece:

Bir yaparsanız alias unbuffer='unbuffer '(izleyen boşluğa dikkat edin), sonra takma adlar sonra genişletilecektir unbuffer.


Kabul edilen takma adlara dikkat edin - yerleşikler ve işlevler gibi diğer kabuk yapılarıyla da çalışmaz.
Amir

4
Bir yaparsanız alias unbuffer='unbuffer '(izleyen boşluğa dikkat edin), sonra takma adlar sonra genişletilecektir unbuffer.
Stéphane Chazelas 18:16

unbufferbu! sudo apt install expect- Belirsizdi.
loxaxs

22

Araç setlerinin tarihi

Böyle bir aracı isteyen ilk kişi sen değilsin. İnsanlar 30 yıldır böyle araçlar istiyor. Ve onlar da neredeyse o kadar uzun süredir var.

Bu tür bir şey için ilk araç, Rich Salz tarafından 1990'ların başında nethack (sic!) Aldatmak için yazdığı Bernstein'ın "Ginsu bıçağı" olarak nitelendirdiği “Saldırı” paketi olan Daniel J. Bernstein'dı. "Pty" paketinin 4. sürümü 1992'de comp.sources.unix(cilt 25 sayı 127 - 135) yayınlandı. World Wide Web’de hala bulunabiliyor. Paul Vixie bunu zamanında tarif etti:

Ne söyleyebilirim? Dilimler, dices eder, bulaşıkları yıkar, köpeğe doğru yürür. "Sadece işe yarıyor" anlamına gelir, yani yönergeleri izlerseniz, herhangi bir saç çekmeden veya diş gıcırdatmadan veya diğer standart taşıma etkinlikleri olmadan bir çalışma paketi elde edersiniz.

Bernstein daha sonra, bir süre önce açıkladığı bir "ptyget" paketi ile 1999-04-07 tarihinde veya öncesinde bunu güncelledi:

Yeni bir sahte-tahsisatçı, ptyget'ı bir araya getirdim. Alfa sürümü ftp://koobera.math.uic.edu/pub/software/ptyget-0.50.tar.gz. Bir ufak posta listesi var; katılmak için boş bir mesaj gönderin djb-ptyget-requ...@koobera.math.uic.edu. Ptyget'ın arayüzünü sıfırdan tasarladım. Pty'den çok daha modüler; temel pty arayüzü şimdi üç parçaya bölünmüştür:

  • ptyget: küçük, düşük seviyeli bir program - paketteki tek programlı program - yeni bir takma ad tahsis eder ve seçtiğiniz programa geçirir
  • ptyspawn: bir çocuk sürecini sahte bir isim altında yürüten, çıkışını bekleyen ve durakları izleyen başka bir küçük program
  • ptyio: başka, sadece biraz daha büyük, verileri ileri geri götüren program

Eski Ginsu bıçağı ptyşimdi yazıldığından ptybandage, bunun eş anlamlısı ptyget ptyio -t ptyspawn; pty -d, ağ programlarını sözde ttys'lere eklemek için şimdi yazıldığından ptyrun, bunun bir eş anlamlısı ptyget ptyio ptyspawn; ve nobufeşanlamlıdır ptyget ptyio -r ptyspawn -23x. Oturum yönetimi özelliklerini ayrı bir pakete böldüm.

Bu ayrı paket "sess" paketiydi.

"ptyget", tesadüfen, Berstein’ın kendi yayınlanmayan "yineleyen" yapı sisteminin çok erken bir versiyonunu ve yayınlanmış birkaç örneğinden birini örneklemede dikkat çekicidir. dependonaçık bir habercisidir redo-ifchange.

kullanım

ptybandage

ptybandageinsanların genellikle bir oturum açma oturumunda istedikleri şeydir. Birincil kullanım durumu, standart girişlerinin, çıkışlarının veya hatalarının terminallere bağlı olup olmadığına duyarlı olan programları, aslında kabuk boru hatlarında olsalar da veya standart dosya tanımlayıcılarının dosyaya yönlendirilmiş olmasına rağmen, bu şekilde çalışmasını sağlamaktır.

Bu (tabii ki, uygun bir dış komut olması gerekir) çalıştırmak için bir komut alır ve standart girdi, çıktı, hata ve üzerine bu bağlantı, bir terminal bağlı olduğu düşündüğü şekilde çalıştırır ptybandage's orijinal standart giriş, çıkış ve hata.

İş kontrol kabukları altında çalışmanın nüansları ile ilgilenerek, bir terminal STOP karakterinin sadece durmakla ptybandagekalmayıp, aynı zamanda iç terminale bağlı programı durdurmasını sağlar.

ptyrun

ptyrunİnsanların genellikle TCP ağ sunucularında istedikleri şeydir. Birincil kullanım durumu, kendileri terminal oluşturmayan, terminal olmadığında istenildiği gibi çalışmayan programları çalıştıran uzaktan çalıştırma ortamlarıdır.

İş denetim kabuğu altında çalışmayı beklemiyor ve çalıştırılan komut bir durdurma sinyali alıyorsa, basitçe yeniden başlatılıyor.

Mevcut araç setleri

Dru Nelson hem "pty" sürüm 4 hem de "ptyget" ı yayınlar.

Paul Jarc, işletim sistemlerinin gerçekte sunmadığı orijinal sistemde işletim sistemine özgü sahte terminal aygıtı ile uğraşmaya çalışan sabit bir ptyget sürümü yayınlıyor.

Nosh kaynak paketi , Laurent Bercot'un aracını ve nosh paketinin kendi sözde-terminal yönetim komutlarını kullanan çalışma ptybandangeve ptyrunsenaryolar ile birlikte gelir execline. Noosh 1.23 sürümünden itibaren bunlar, nosh-terminal-extras paketinde önceden paketlenmiş olarak bulunmaktadır. (Daha önceki sürümler onları yalnızca kaynaktan inşa eden kişilere sağladı.)

Birkaç örnek kullanır

Jurjgen Oskamptybandage , burada bir belgedeki girdiyi açık bir şekilde açıp bir parola istemi için kontrol terminalini okuyan bir programa girdi beslemek için AIX üzerinde kullanıyor :

$ ptybandage dsmadmc << EOF> uit.txt
joskam
parola
sorgu oturumu
sorgu işlemi
bırakmak, vazgeçmek
EOF

Andy Bradford ptyrun, OpenBSD'yi daemontools ve ucspi-tcp altında kullanarakbgplgsh etkileşimli yönlendirici kontrol programını ağ üzerinden erişilebilir kılmak için kullanırken terminalden bahsettiğini düşündürür:

#! / Bin / sh
exec 2> & 1
exec envuidgid rviews tcpserver -vDRHl0 0 23 ptyrun / usr / bin / bgplgsh

daha fazla okuma


Tarihteki ders için teşekkürler, fakat önerdiğiniz araçlar modern bir Linux dağıtımında mevcut değil, bu yüzden faydalı değil.
Amir

4
Köprüler bir demet ve araçlar kesinlikle nerede adanmış cevabın bütün bir bölümü var olan mevcut.
JdeBP

1
Senin fikrin ne expect?
CMCDragonkai

20

Socat'ı işleminize bağlı bir pty ile başlatmak için socat'ı kullanabilir ve pty'nin diğer ucunu bir dosyaya bağlamak için socat'ı kullanabilirsiniz. Hangi AFAIU tam olarak istediğiniz şeydi:

socat EXEC:"my-command",pty GOPEN:mylog.log

Bu yöntem neden olacak isattytarafından çağrılan my-commanddönmek trueve bu konuda sadece dayanan bir işlem çıkış kontrol kodlarına aptal edilecektir. Bazı işlemlerin (özellikle de grep) TERMortam değişkeninin değerini de kontrol ettiğini , bu nedenle"xterm"


13

Burada Süper Kullanıcı'da KarlC tarafından yayınlanan hoş bir çözüm de var :

Küçük bir paylaşılan kütüphaneyi derleyin:

echo "int isatty(int fd) { return 1; }" | gcc -O2 -fpic -shared -ldl -o isatty.so -xc -

Ardından, bu isatty(3)geçersiz kılmayı dinamik olarak yükleme komutunuza söyleyin :

LD_PRELOAD=./isatty.so mycommand

Bu, oradaki her komut için işe yaramayabilir, hatta beklenmedik şekillerde bazılarını bile kırabilir, ancak çoğu durumda işe yarayabilir.


2
MacOS kullanıcıları için de aynı davranışı kullanarakDYLD_INSERT_LIBRARIES=./isatty.so DYLD_FORCE_FLAT_NAMESPACE=y mycommand
Christopher Shroba

12

Kullanmaya ne dersin script(1)?

Örneğin:

script -q -c 'ls -G' out_file

Kurtaracak lsçıktı out_filerenk kodları korunmuş ile.


Bu burada çalışmıyor. Renkler nasıl korunur? out_fileRenkleri ile çıktı almak için kullanmam gereken bir araç var mı ?
Kira

1
@ ANSI renk kaçış dizileri ile dosyaları görüntülemek için Kira kullanıyorum less -R. Yine de bu durumda çıktıların terminalimde sona eren boru hattında devam etmesini istedim. Gösterim catamacıyla kullanıldığında script -q -c 'ls -G' /dev/null | cat, typescriptdosyayı tamamen gizleyen ve yalnızca programın çıktısını bırakan bir şeydi .
Amir

Bir dosya oluşturmaktan kaçınmak için, örnek -olarak scriptçıktı dosyası olarak bir tire ( ) kullanın :script -q -c 'ls -G' -
Franklin Piat

0

Dayanarak Amir'in cevabı @ , burada oluşturur ve daha sonra zamanında kütüphane içerir bir script:

#!/bin/bash
set -euo pipefail

function clean_up {
  trap - EXIT # Restore default handler to avoid recursion
  [[ -e "${isatty_so:-}" ]] && rm "$isatty_so"
}
# shellcheck disable=2154 ## err is referenced but not assigned
trap 'err=$?; clean_up; exit $err' EXIT HUP INT TERM

isatty_so=$(mktemp --tmpdir "$(basename "$0")".XXXXX.isatty.so)
echo "int isatty(int fd) { return 1; }" \
  | gcc -O2 -fpic -shared -ldl -o "$isatty_so" -xc -
# Allow user to SH=/bin/zsh faketty mycommand
"${SH:-$SHELL}" -c 'eval $@' - LD_PRELOAD="$isatty_so" "$@"
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.