Lấy chiều rộng bàn điều khiển bằng cách sử dụng tập lệnh bash


15

Tôi đang gặp một vấn đề trong đó tôi đang cố gắng để có được kích thước của một thiết bị đầu cuối bằng cách sử dụng các tập lệnh. Thông thường tôi sẽ sử dụng lệnh tput colsbên trong bàn điều khiển, tuy nhiên tôi muốn có thể thực hiện tính năng này bằng cách sử dụng nghiêm ngặt các tập lệnh.

Đến bây giờ tôi có thể phát hiện bàn điều khiển đang chạy và lấy đường dẫn tệp của nó. Tuy nhiên, tôi đang vật lộn để sử dụng thông tin này để có được chiều rộng của giao diện điều khiển. Tôi đã thử sử dụng lệnh tput, nhưng tôi khá mới đối với Linux / script vì vậy không thực sự biết phải làm gì.

Lý do để làm điều này là tôi muốn có thể thiết lập một mục cron thông báo cho bàn điều khiển về chiều rộng / cột của nó thường xuyên.

Đây là mã của tôi cho đến nay:

tty.sh

#!/bin/bash

#Get PID of terminal
#terminal.txt holds most recent PID of console in use
value=$(</home/test/Documents/terminal.txt)

#Get tty using the PID from terminal.txt
TERMINAL="$(ps h -p $value -o tty)"
echo $TERMINAL

#Use tty to get full filepath for terminal in use
TERMINALPATH=/dev/$TERMINAL
echo $TERMINALPATH

COLUMNS=$(/home/test/Documents/get_columns.sh)
echo $COLUMNS

get_columns.sh

#!/usr/bin/env bash
echo $(/usr/bin/tput cols)

Đầu ra bình thường của TERMINAL& TERMINALPATHare và , ví dụ &pts/terminalnumber/dev/pts/terminalnumberpts/0/dev/pts/0



@phk Tôi không nghĩ là có ích. Vấn đề là làm thế nào để nói với trình điều khiển tty các giá trị thực cho các cột / dòng. Đây là để xác định chúng từ trình điều khiển tty.
roaima

Tôi không nghĩ rằng croncông việc đã kiểm soát các thiết bị đầu cuối.
TMN

Câu trả lời:


17

Các tputlệnh là một công cụ tuyệt vời, nhưng tiếc là nó không thể lấy các thiết lập thực sự cho một thiết bị đầu cuối được lựa chọn tùy ý.

Lý do cho điều này là vì nó đọc tiêu chuẩn cho các đặc điểm của thiết bị đầu cuối, và đây cũng là nơi nó viết câu trả lời của nó. Vì vậy, thời điểm bạn cố gắng nắm bắt đầu ra của tput colsbạn cũng đã loại bỏ nguồn thông tin của nó.

May mắn thay, sttyđọc stdin thay vì stdout để xác định các đặc điểm của thiết bị đầu cuối, vì vậy đây là cách bạn có thể truy xuất thông tin kích thước bạn cần:

terminal=/dev/pts/1
columns=$(stty -a <"$terminal" | grep -Po '(?<=columns )\d+')
rows=$(stty -a <"$terminal" | grep -Po '(?<=rows )\d+')

Nhân tiện, nó không cần thiết phải viết như thế này echo $(/usr/bin/tput cols).

Đối với bất kỳ cấu trúc nào echo $(some_command)bạn đang chạy some_commandvà nắm bắt đầu ra của nó, sau đó bạn chuyển echosang đầu ra. Trong hầu hết mọi tình huống bạn có thể tưởng tượng bạn cũng có thể vừa chạy some_commandvà để nó phân phối đầu ra trực tiếp. Nó hiệu quả hơn và cũng dễ đọc hơn.


Mà thực hiện / phiên bản của tput/ nurses? Của tôi (ncurses 6.0.20160625) TIOCGWINSZ trên stderr nếu nó không thể làm điều đó trên thiết bị xuất chuẩn. cols=$(tput cols)hoặc cols=$(tput cols 2<> /dev/ttyx) hoạt động tốt.
Stéphane Chazelas

@ StéphaneChazelas Tôi đã nhận được 5.9 + 20140913-1 + b1 ban đầu được cài đặt từ Debian "sid". Chỉ cần tìm một phiên bản mới hơn bây giờ.
roaima

1
Làm việc tốt với ncurses 5.7.20100313ở đây. Bạn có tích cực cols=$(tput cols 2<> /dev/tty1)không làm việc cho bạn?
Stéphane Chazelas

@ StéphaneChazelas hấp dẫn. Bạn nói đúng: nếu tôi di chuyển ra khỏi thiết bị đầu cuối, tput colsthì đọc từ thiết bị xuất chuẩn . Bây giờ tôi cần tìm ra cách viết lại câu trả lời của mình ...
roaima

1
Tôi sẽ sử dụng stty size <"$terminal" | read rows columnsthay vì cố gắng phân tíchstty -a
Random832

13

tput colstput linestruy vấn kích thước của thiết bị đầu cuối (từ trình điều khiển thiết bị đầu cuối, chứ không phải chính thiết bị đầu cuối) từ thiết bị đầu cuối trên thiết bị xuất chuẩn của nó và nếu thiết bị xuất chuẩn không phải là thiết bị đầu cuối như trong trường hợp cols=$(tput cols)đó là đường ống, từ thiết bị đầu cuối .

Vì vậy, để lấy các giá trị từ một thiết bị đầu cuối tùy ý, bạn cần mở thiết bị đó trên thiết bị tput:

{ cols=$(tput cols) rows=$(tput lines); } 2< "$TERMINALPATH"

(ở đây mở ở chế độ chỉ đọc nên tputkhông xuất ra thông báo lỗi của nó ở đó).

Ngoài ra, bạn có thể sử dụng stty size. sttytruy vấn thiết bị đầu cuối trên stdin:

read rows cols < <(stty size < "$TERMINALPATH")

Không ai trong số đó là tiêu chuẩn nên có thể (và trong thực tế sẽ) không hoạt động trên tất cả các hệ thống. Nó khá dễ mang theo các hệ thống GNU / Linux.

Việc bổ sung stty sizehoặc phương pháp khác để truy vấn kích thước thiết bị đầu cuối đã được yêu cầu cho POSIX nhưng cuộc thảo luận dường như không đi đến đâu.


8

Kịch bản này:

#!/bin/bash

echo "The number of columns are $COLUMNS"
echo "The number of lines are $LINES"

Làm việc ở đây hoàn toàn không có gì nữa .....

Tại sao bạn đang thiết lập một biến môi trường với dữ liệu? COLUMNS = $ (/ nhà / kiểm tra / Tài liệu / get_columns.sh)

Bạn đang cố gắng để có được các cột và dòng từ kịch bản khác hoặc tty? Là nó? Vẫn còn lạ đối với tôi vì bạn đang đặt biến môi trường cột cho tập lệnh cục bộ ....


Điều này không giúp lấy lại các giá trị trong croncông việc của OP cho một thiết bị đầu cuối cụ thể.
roaima

1
À? Gì? Bây giờ tôi đang bối rối hơn, làm thế nào các kịch bản cronjobs có thể có chiều rộng ????? Họ thực sự không chạy trong một thiết bị đầu cuối.
Luciano Andress Martini

Tôi biết. Công cronviệc truy vấn một thiết bị đầu cuối cụ thể cho các đặc điểm của nó. (Tôi không hoàn toàn chắc chắn lý do tại sao nó cần phải làm điều này, nhưng đó là những gì OP muốn.)
roaima

@LucianoAndressMartini $ COLUMNS và $ LINES là các biến bash, nó không hoạt động (ví dụ) trong dấu gạch ngang và posh
ingroxd

Tks. Tôi thực sự biết, nhưng kịch bản của tôi là hashbang với / bin / bash tôi nghĩ rằng nó được cho là để bạn biết rằng bạn nên sử dụng nó. Nếu bạn đang sử dụng một số unix mà không có bash, có lẽ câu trả lời của tôi không dành cho bạn.
Luciano Andress Martini

0

Câu trả lời của tôi khác với câu trả lời của Roaima, vì nó năng động. Câu trả lời của anh ấy / Hers cho bạn kích thước của thiết bị đầu cuối khi tạo. Nếu bạn đang sử dụng một trình quản lý cửa sổ ốp lát, như i3 hoặc bspwm, bạn muốn có chiều rộng hiện tại của thiết bị đầu cuối. Vì vậy, tôi sử dụng ssty từ gói coreutils:

#!/bin/bash
stty size | awk '{print $2}'

Giải pháp của Luciano hoạt động hoàn hảo trong xterm và xfce4-terminal. Tôi không biết nếu tất cả các thiết bị đầu cuối thiết lập biến $ COLUMNS.


Đây không phải là năng động hơn câu trả lời của tôi. Cả hai đều cung cấp cho bạn kích thước thiết bị đầu cuối tại điểm bạn chạy các lệnh.
roaima
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.