STDIN, STDOUT veya STDERR'ın betiğinize / betiğinden boru olup olmadığını belirlemenin kusursuz bir yolu yoktur ssh
.
"Normalde" çalışan şeyler
Örneğin, aşağıdaki bash çözümü etkileşimli bir kabukta düzgün çalışır:
[[ -t 1 ]] && \
echo 'STDOUT is attached to TTY'
[[ -p /dev/stdout ]] && \
echo 'STDOUT is attached to a pipe'
[[ ! -t 1 && ! -p /dev/stdout ]] && \
echo 'STDOUT is attached to a redirection'
Ama her zaman çalışmazlar
Ancak, bu komutu TTY olmayan bir komut olarak yürütürken ssh
, STD akışları her zaman yönlendiriliyor gibi görünür. Bunu göstermek için STDIN'i kullanmak daha kolay çünkü:
# CORRECT: Forced-tty mode correctly reports '1', which represents
# no pipe.
ssh -t localhost '[[ -p /dev/stdin ]]; echo ${?}'
# CORRECT: Issuing a piped command in forced-tty mode correctly
# reports '0', which represents a pipe.
ssh -t localhost 'echo hi | [[ -p /dev/stdin ]]; echo ${?}'
# INCORRECT: Non-tty mode reports '0', which represents a pipe,
# even though one isn't specified here.
ssh -T localhost '[[ -p /dev/stdin ]]; echo ${?}'
Neden önemli?
Bu oldukça büyük bir anlaşma çünkü bash betiğinin tty olmayan bir ssh
komutun iletilip iletilmediğini söylemesinin bir yolu olmadığını ima ediyor . Bu talihsiz davranışın ssh
TTY olmayan STDIO için pipo kullanmaya başladığı son sürümlerde ortaya çıktığını unutmayın. Önceki versiyonlar, kullanılarak bash içinden ayırt edilebilen soketler kullanıyordu [[ -S ]]
.
Ne zaman önemli
Bu sınırlama normalde, derlenmiş bir yardımcı programa benzer davranışlara sahip bir bash betiği yazmak istediğinizde sorunlara neden olur cat
. Örneğin, cat
çeşitli giriş kaynaklarını aynı anda işlemede aşağıdaki esnek davranışa izin verir ve TTY olmayan veya zorlamalı TTY ssh
kullanılmasına bakılmaksızın borulu girdi alıp almadığını belirleyecek kadar akıllıdır :
ssh -t localhost 'echo piped | cat - <( echo substituted )'
ssh -T localhost 'echo piped | cat - <( echo substituted )'
Böyle bir şeyi ancak boruların dahil olup olmadığını güvenilir bir şekilde belirleyebiliyorsanız yapabilirsiniz. Aksi takdirde, borulardan veya yeniden yönlendirmeden herhangi bir girdi olmadığında STDIN yazan bir komutun çalıştırılması komut dosyasının asılı kalmasına ve STDIN girişinin beklemesine neden olur.
Çalışmayan diğer şeyler
Bu sorunu çözmeye çalışırken, aşağıdakileri içeren problemler de dahil olmak üzere sorunu çözemeyen çeşitli tekniklere baktım:
- SSH ortam değişkenlerinin incelenmesi
- kullanarak
stat
/ dev / stdin'i dosya göstericisi üzerinde
- etkileşimli modu incelemek
[[ "${-}" =~ 'i' ]]
tty
ve üzerinden tty durumunu incelemetty -s
ssh
durumunun incelenmesi[[ "$(ps -o comm= -p $PPID)" =~ 'sshd' ]]
/proc
Sanal dosya sistemini destekleyen bir işletim sistemi kullanıyorsanız, bir borunun kullanılıp kullanılmadığını belirlemek için STDIO'nun sembolik bağlantılarını takip etme şansınız olabilir. Ancak, /proc
platformlar arası, POSIX uyumlu bir çözüm değildir.
Bu sorunu çözmede son derece ilginçim, bu yüzden işe yarayabilecek başka bir teknik, tercihen hem Linux hem de BSD üzerinde çalışan POSIX tabanlı çözümler düşünüyorsanız lütfen bize bildirin.