Làm thế nào để có được tty trong đó bash đang chạy?


24

Trong phương thức thứ hai được đề xuất bởi trang này , người ta nhận được tty trong đó bash đang được chạy bằng lệnh:

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

Tôi tự nghĩ rằng điều này chắc chắn là hơi lười biếng, liệt kê tất cả các quy trình đang chạy chỉ để trích xuất một trong số chúng. Nó sẽ không hiệu quả hơn (tôi cũng đang hỏi nếu điều này sẽ giới thiệu các hiệu ứng không mong muốn) để làm:

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

FYI, tôi đã gặp vấn đề này bởi vì đôi khi lệnh đầu tiên thực sự mang lại hai (hoặc nhiều hơn) dòng. Điều này sẽ xảy ra ngẫu nhiên, khi có một quá trình khác đang chạy với một PID chứa $$chuỗi con. Trong cách tiếp cận thứ hai, tôi tránh các trường hợp như vậy bằng cách yêu cầu PID mà tôi biết tôi muốn.


6
hiệu quả nhất trong tất cả sẽ là chạy ttylệnh trong phiên bash của bạn. Nếu bạn nhấn mạnh vào sử dụng ps-ps -p $$ -o tty=
iruvar

Câu trả lời:


46

Đơn giản chỉ cần gõ tty:

$ tty 
/dev/pts/20

Quá đơn giản và hiển nhiên là đúng :)

Chỉnh sửa: Cái đầu tiên trả về cho bạn ptyquá trình đang chạy grepnhư bạn có thể nhận thấy:

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

do đó, bạn sẽ cần phải lọc ra grep để chỉ nhận được một kết quả, điều này đang trở nên xấu xí:

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

hoặc sử dụng

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

(một biến thể lành mạnh hơn)


Vâng, đó là giải pháp được đề xuất đầu tiên thực sự (thực tế nó là tty | sed -e "s:/dev/::"). Nhưng tôi nghĩ giải pháp được đề xuất thứ hai trên trang đó không chỉ không hiệu quả, mà còn sai! Tôi sẽ sử dụng ttyvà ngừng phàn nàn mặc dù. :)
Sheljohn

Cái đầu tiên trả về cho bạn ptyquá trình đang chạy grepnhư bạn có thể nhận thấy.
Jakuje

2
Bạn không cần grepnếu bạn đang sử dụng awk. ví dụ: ps ax | awk "/^$$/ {print \$2}"lưu ý việc sử dụng dấu ngoặc kép thay vì dấu ngoặc đơn và dấu ngoặc kép \$2. Nhưng, như bạn nói, sử dụng ttylà giải pháp chính xác.
cas

Cắt xén như thế có thể dẫn đến kết quả khớp sai, ví dụ: nếu PID của bạn là 10 và cũng có PID 103. Sử dụngawk -vpid=$$ '$1 == pid {print $2}'
Barmar

Tôi chỉ lưu ý ở đây rằng sinh sản ttytrong node.js hoàn toàn không hoạt động, trong khi psvà bạn bè hoạt động tốt.
Steven Lu

17

Nếu bạn muốn hiệu quả hơn, thì đúng, bạn pscó thể lọc chỉ quy trình đang được đề cập (và sẽ chính xác hơn, không gặp rủi ro khi chọn các lệnh xảy ra để có số quy trình của bạn trong tên của họ ). Không chỉ vậy, nhưng có thể được yêu cầu không tạo tiêu đề (tùy chọn h), loại bỏ tailquá trình và chỉ hiển thị TTYtrường (tùy chọn o tty), loại bỏ awkquá trình.

Vì vậy, đây là lệnh giảm của bạn:

ps hotty $$

10

Những cách khác để làm điều đó:

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.

(Nếu bạn đang ở trong một vỏ mà stdin, stdout và stderr không được kết nối với thiết bị đầu cuối kiểm soát của nó, bạn có thể đưa một bộ lọc dữ liệu đến thiết bị đầu cuối kiểm soát bằng cách mở /dev/tty :

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

)

Hoặc với ps:

ps h -o tty -p $$ #no header (h); print tty column; for pid $$

2
(1) Tôi rất vui vì bạn nhận ra rằng tty hiện tại / kiểm soát của một quá trình không được liên kết với bất kỳ mô tả tệp nào và không được đảm bảo để mở trên bất kỳ fd nào. Nhưng, bạn đã thử lệnh mà bạn đưa ra như một cách giải quyết cho tình huống đó chưa? Khi tôi thử nó, tất cả những gì tôi nhận được là /dev/tty, và không phải là tty kiểm soát (như báo cáo của ps). (2) Tôi tin rằng { readlink /dev/fd/0; } < /dev/tty(và sẽ luôn luôn) tương đương với readlink /dev/fd/0 < /dev/tty- bạn có tin khác không? Nếu vậy, bạn có thể biện minh cho nó? (3) Dấu chấm phẩy thứ hai trong lệnh của bạn (cái sau /dev/tty) là không cần thiết.
Scott

6

Chỉ để hoàn thiện, trong khi các lệnh ps khác được đề cập hoạt động trên Linux, ps -p $$ -o tty=(như được đề cập bởi @ 1_CR) là khả năng di động nhất đối với tất cả các hệ thống Unix hiện đại, vì nó chỉ sử dụng các tùy chọn được xác định trong Tiêu chuẩn Unix .


2

Trong shell tương tác, người ta có thể sử dụng wlệnh cho điều đó. Trong ví dụ dưới đây, wcác báo cáo được chạy bởi người dùng cụ thể và tất nhiên nó hiển thị TTY nơi lệnh đó đang được chạy.

$ 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.