รับความกว้างคอนโซลโดยใช้สคริปต์ทุบตี


15

ฉันพบปัญหาที่ฉันพยายามเพิ่มขนาดของเทอร์มินัลโดยใช้สคริปต์ โดยปกติแล้วฉันจะใช้คำสั่งtput colsภายในคอนโซล แต่ฉันต้องการที่จะสามารถบรรลุคุณสมบัตินี้โดยใช้สคริปต์อย่างเคร่งครัด

ณ ตอนนี้ฉันสามารถตรวจจับคอนโซลการทำงานและรับเส้นทางไฟล์ของมันได้ อย่างไรก็ตามฉันพยายามที่จะใช้ข้อมูลนี้เพื่อให้ได้ความกว้างของคอนโซล ฉันพยายามใช้คำสั่งtputแต่ฉันค่อนข้างใหม่สำหรับ Linux / สคริปต์ดังนั้นจึงไม่รู้จริงๆว่าต้องทำอย่างไร

เหตุผลในการทำเช่นนี้คือฉันต้องการที่จะสามารถตั้งค่ารายการcronที่แจ้งคอนโซลของความกว้าง / คอลัมน์ทุกครั้ง

นี่คือรหัสของฉัน:

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)

ผลลัพธ์ปกติของTERMINAL& TERMINALPATHเป็นและตัวอย่างเช่น&pts/terminalnumber/dev/pts/terminalnumberpts/0/dev/pts/0


1
unix.stackexchange.com/questions/16578/…อาจช่วยคุณได้
phk

@phk ฉันไม่คิดว่าจะช่วย ปัญหามีวิธีบอกไดรเวอร์ tty ของค่าจริงสำหรับคอลัมน์ / บรรทัด นี่คือการตรวจสอบพวกเขาจากไดรเวอร์ tty
roaima

ฉันไม่คิดว่าcronงานจะมีการควบคุมอาคาร
TMN

คำตอบ:


18

tputคำสั่งเป็นเครื่องมือที่ดี แต่โชคร้ายที่มันไม่สามารถเรียกคืนการตั้งค่าที่แท้จริงสำหรับสถานีที่เลือกโดยพลการ

เหตุผลสำหรับสิ่งนี้คือมันอ่านstdoutสำหรับคุณลักษณะของเทอร์มินัลและนี่ก็เป็นที่ที่มันเขียนคำตอบ ดังนั้นช่วงเวลาที่คุณพยายามจับเอาท์พุทของtput colsคุณได้ลบแหล่งข้อมูลของมันด้วย

โชคดีที่sttyอ่านstdinแทนที่จะเป็นstdoutสำหรับการกำหนดคุณสมบัติของเทอร์มินัลดังนั้นนี่คือวิธีที่คุณสามารถดึงข้อมูลขนาดที่คุณต้องการ:

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

echo $(/usr/bin/tput cols)โดยวิธีการที่มันยุ่งยากโดยไม่จำเป็นที่จะเขียนนี้เป็น

สำหรับสิ่งปลูกสร้างใด ๆ ที่echo $(some_command)คุณกำลังเรียกใช้some_commandและเก็บเอาท์พุทของมันซึ่งคุณจะผ่านไปechoยังเอาท์พุท ในเกือบทุกสถานการณ์คุณสามารถจินตนาการได้ว่าคุณอาจต้องวิ่งsome_commandและปล่อยให้มันส่งออกโดยตรง มันมีประสิทธิภาพมากกว่าและอ่านง่ายกว่า


การใช้งาน / รุ่นของtput/ nurses? Mine (ncurses 6.0.20160625) ทำการ TIOCGWINSZ บน stderr หากไม่สามารถทำได้ใน stdout cols=$(tput cols)หรือcols=$(tput cols 2<> /dev/ttyx) ทำงานได้ดี
Stéphane Chazelas

@ StéphaneChazelasฉันมี 5.9 + 20140913-1 + b1 เดิมติดตั้งจาก Debian "sid" เพียงมองหารุ่นที่ใหม่กว่าในขณะนี้
roaima

1
ทำงานได้ดีกับncurses 5.7.20100313ที่นี่ คุณคิดบวกแล้วcols=$(tput cols 2<> /dev/tty1)ไม่ได้ผลกับคุณเหรอ?
Stéphane Chazelas

@ StéphaneChazelasที่น่าสนใจ คุณกำลังขวา: ถ้าผมย้ายstdoutห่างจากขั้ว, tput colsไม่อ่านจากstderr ตอนนี้ผมต้องทำงานออกวิธีการเขียนคำตอบของฉัน ...
roaima

1
ฉันจะใช้stty size <"$terminal" | read rows columnsแทนการพยายามวิเคราะห์stty -a
สุ่ม 832

13

tput colsและtput linesสอบถามขนาดของเทอร์มินัล (จากไดรเวอร์อุปกรณ์เทอร์มินัลไม่ใช่เครื่องเทอร์มินัล) จากอุปกรณ์เทอร์มินัลใน stdout และถ้า stdout ไม่ใช่อุปกรณ์เทอร์มินัลเช่นในกรณีcols=$(tput cols)ที่เป็นไปป์จาก stderr

ดังนั้นในการดึงค่าจากอุปกรณ์ปลายทางคุณต้องเปิดอุปกรณ์นั้นบน stderr ของtput:

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

(ที่นี่เปิดในโหมดอ่านอย่างเดียวจึงtputไม่ส่งข้อความแสดงข้อผิดพลาดที่นั่น)

stty sizeหรือคุณอาจจะไม่สามารถที่จะใช้sttyเคียวรีเทอร์มินัลบน stdin:

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

ไม่มีสิ่งใดที่เป็นมาตรฐานดังนั้นอาจ (และในทางปฏิบัติ) จะไม่ทำงานในทุกระบบ มันควรจะพกพาได้ดีกับระบบ GNU / Linux

การเพิ่มstty sizeหรือวิธีอื่น ๆ ในการสืบค้นขนาดเทอร์มินัลถูกร้องขอไปยัง POSIXแต่ดูเหมือนว่าการสนทนาจะไม่เกิดขึ้นที่ใดก็ตาม


9

สคริปต์นี้:

#!/bin/bash

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

ทำงานที่นี่ไม่มีอะไรอีกแล้ว .....

ทำไมคุณถึงตั้งค่าตัวแปรสภาพแวดล้อมด้วยข้อมูล คอลัมน์ = $ (/ home / ทดสอบ / เอกสาร / get_columns.sh)

คุณพยายามรับคอลัมน์และบรรทัดจากสคริปต์หรือ tty อื่นหรือไม่ มันคืออะไร ยังแปลกสำหรับฉันเพราะคุณกำลังตั้งค่าตัวแปรสภาพแวดล้อมคอลัมน์สำหรับสคริปต์ท้องถิ่น ...


สิ่งนี้ไม่ได้ช่วยดึงค่าภายในcronงานของ OP สำหรับเทอร์มินัลเฉพาะ
roaima

1
Ahn? อะไร? ตอนนี้ฉันสับสนมากขึ้นสคริปต์ cronjobs จะมีความกว้างได้อย่างไร ????? จริงๆแล้วพวกเขาไม่ได้ทำงานในอาคารผู้โดยสาร
Luciano Andress Martini

ฉันรู้ว่า. cronงาน queries ขั้วโดยเฉพาะอย่างยิ่งสำหรับลักษณะของ (ฉันไม่แน่ใจว่าทั้งหมดว่าทำไมมันต้องทำแบบนี้ แต่ที่สิ่งที่ OP ต้องการ.)
roaima

@LucianoAndressMartini $ COLUMNS และ $ LINES เป็นตัวแปรทุบตีมันไม่ทำงาน (ตัวอย่าง) ใน dash และ posh
ingroxd

Tks ฉันรู้จริงๆ แต่สคริปต์ของฉันคือ hashbang ด้วย / bin / bash ฉันคิดว่ามันควรที่คุณจะรู้ว่าคุณควรใช้มัน ถ้าคุณใช้ยูนิกซ์ที่ไม่มี bash บางทีคำตอบของฉันอาจไม่เหมาะกับคุณ
Luciano Andress Martini

1

คำตอบของฉันแตกต่างจากของ Roaima เนื่องจากเป็นแบบไดนามิก คำตอบของเขา / เธอให้ขนาดของเทอร์มินัลเมื่อสร้าง หากคุณเป็นตัวอย่างโดยใช้ตัวจัดการหน้าต่างแบบเรียงต่อกันเช่น i3 หรือ bspwm คุณต้องการมีความกว้างปัจจุบันของเทอร์มินัล ดังนั้นฉันใช้ ssty จากแพ็คเกจ coreutils:

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

โซลูชันของ Luciano ทำงานได้อย่างไร้ที่ติในเทอร์มินัล xterm และ xfce4 ฉันไม่รู้ว่าเทอร์มินัลทั้งหมดตั้งค่าตัวแปร $ COLUMNS หรือไม่


นี่ไม่ใช่แบบไดนามิกอีกต่อไปแล้วคำตอบของฉัน ทั้งสองให้ขนาดเทอร์มินัลที่จุดที่คุณเรียกใช้คำสั่ง
roaima
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.