Bagaimana cara mendapatkan tty di mana bash berjalan?

25

Dalam metode kedua yang diusulkan oleh halaman ini , seseorang mendapatkan tty di mana bash dijalankan dengan perintah:

ps ax | grep $$ | awk '{ print $2 }'

Saya pikir pada diri saya sendiri bahwa ini agak malas, mendaftar semua proses yang berjalan hanya untuk mengekstrak salah satunya. Apakah itu tidak lebih efisien (saya juga bertanya apakah ini akan menimbulkan efek yang tidak diinginkan) untuk dilakukan:

ps -p $$ | tail -n 1 | awk '{ print $2 }'

FYI, saya menemukan masalah ini karena kadang-kadang perintah pertama benar-benar menghasilkan dua (atau lebih) baris. Ini akan terjadi secara acak, ketika akan ada proses lain yang berjalan dengan PID yang berisi $$sebagai substring. Dalam pendekatan kedua, saya menghindari kasus-kasus seperti itu dengan meminta PID yang saya tahu saya inginkan.

Sheljohn
sumber
6
nah paling efisien dari semua akan menjalankan ttyperintah dalam sesi bash Anda. Jika Anda bersikeras menggunakan ps-ps -p $$ -o tty=
iruvar

Jawaban:

47

Cukup dengan mengetik tty:

$ tty 
/dev/pts/20

Terlalu sederhana dan jelas untuk menjadi kenyataan :)

Sunting: Yang pertama mengembalikan Anda juga ptydari proses yang berjalan grepkarena Anda dapat melihat:

$ ps ax | grep $$
28295 pts/20   Ss     0:00 /bin/bash
29786 pts/20   S+     0:00 grep --color=auto 28295

karena itu Anda perlu memfilter grep untuk mendapatkan hanya satu hasil, yang semakin jelek:

ps ax | grep $$ | grep -v grep | awk '{ print $2 }'

atau menggunakan

ps ax | grep "^$$" | awk '{ print $2 }'

(varian yang lebih waras)

Jakuje
sumber
Ya, memang itulah solusi yang disarankan pertama (sebenarnya itu tty | sed -e "s:/dev/::"). Tapi saya pikir solusi kedua yang disarankan pada halaman itu tidak hanya tidak efisien, tetapi juga salah! Saya akan menggunakan ttydan berhenti mengeluh. :)
Sheljohn
Yang pertama mengembalikan Anda juga ptyproses yang berjalan grepseperti yang Anda sadari.
Jakuje
2
Anda tidak perlu grepjika menggunakan awk. misalnya ps ax | awk "/^$$/ {print \$2}"- perhatikan penggunaan tanda kutip ganda daripada tanda kutip tunggal dan lolos \$2. Tetapi, seperti yang Anda katakan, menggunakan ttyadalah solusi yang tepat.
cas
Grepping seperti itu dapat menghasilkan pasangan yang salah, misalnya jika PID Anda 10 dan ada juga PID 103. Gunakanawk -vpid=$$ '$1 == pid {print $2}'
Barmar
Saya hanya mencatat di sini bahwa pemijahan ttydi node.js tidak bekerja sama sekali, sementara psdan teman-teman bekerja dengan baik.
Steven Lu
17

Jika Anda ingin lebih efisien, maka ya, Anda benar yang psdapat memfilter hanya proses yang dimaksud (dan itu akan lebih benar, tidak menjalankan risiko mengambil perintah yang kebetulan memiliki nomor proses Anda dalam nama mereka. ). Tidak hanya itu, tetapi dapat dikatakan untuk tidak menghasilkan header (opsi h), menghilangkan tailproses, dan hanya menampilkan TTYbidang (opsi o tty), menghilangkan awkproses.

Jadi, inilah perintah Anda yang dikurangi:

ps hotty $$
Toby Speight
sumber
10

Cara lain untuk melakukannya:

readlink /dev/fd/0     #or 1 or 2 
readlink /proc/self/fd/0 #or 1 or 2
readlink -f /dev/stdin #or stdout or stderr; f to resolve recursively
#etc.

(Jika Anda berada di shell yang stdin, stdout, dan stderr tidak terhubung ke terminal pengendali, Anda bisa mendapatkan deskriptor resmi ke terminal pengendali dengan membuka /dev/tty:

( { readlink /dev/fd/0; } </dev/tty; ) </dev/null  >output 2>&1

)

Atau dengan ps:

ps h -o tty -p $$ #no header (h); print tty column; for pid $$
PSkocik
sumber
2
(1) Saya senang Anda menyadari bahwa tty saat ini / mengendalikan proses tidak terkait dengan deskriptor file, dan tidak dijamin terbuka pada fd apa pun. Tetapi, apakah Anda mencoba perintah yang Anda tawarkan sebagai solusi untuk kemungkinan itu? Ketika saya mencobanya, yang saya dapatkan hanyalah /dev/tty, dan bukan tty pengendali (seperti yang dilaporkan oleh ps). (2) Saya percaya itu { readlink /dev/fd/0; } < /dev/tty(dan akan selalu) setara dengan readlink /dev/fd/0 < /dev/tty- apakah Anda percaya sebaliknya? Jika demikian, dapatkah Anda membenarkannya? (3) Titik koma kedua di perintah Anda (yang setelah /dev/tty) tidak perlu.
Scott
6

Hanya untuk kelengkapan, sementara perintah ps lain yang disebutkan berfungsi di Linux, ps -p $$ -o tty=(sebagaimana disebutkan oleh @ 1_CR) adalah yang paling portabel untuk semua sistem Unix modern, karena hanya menggunakan opsi yang ditentukan dalam Standar Unix .

Random832
sumber
2

Dalam shell interaktif, seseorang dapat menggunakan wperintah untuk itu. Dalam contoh di bawah ini, wlaporan itu sendiri dijalankan oleh pengguna tertentu, dan tentu saja itu menunjukkan TTY di mana perintah itu dijalankan.

$ w
 11:20:08 up 5 min,  3 users,  load average: 0.34, 0.39, 0.20
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
xieerqi  :0       :0               11:15   ?xdm?   1:47   0.34s init --user
xieerqi  pts/0    :0               11:18   23.00s  0.05s  0.05s /bin/mksh
xieerqi  pts/10   :0               11:20    0.00s  0.03s  0.01s w
Sergiy Kolodyazhnyy
sumber