จะระบุเทอร์มินัลจากสคริปต์ได้อย่างไร?


8

และไม่ได้พูดว่า " $TERM" - xtermมันเสมอ

วิธีสามารถbashสคริปต์บอกสิ่งที่ขั้วมันทำงานในโดยเฉพาะไม่ว่าจะเป็น iTerm, Terminal.app หรือจริง xterm?

ฉันถามเพราะresetไม่ทำงานนอกกรอบบน Terminal.app และ iTerm2 อย่างไรก็ตาม iTerm2 รู้จักลำดับการหลบหนีสำหรับทำการรีเซ็ตเทอร์มินัล ( \x1b]50;ClearScrollback\x07) และหากฉันตรวจพบได้ฉันสามารถลบล้างresetด้วยนามแฝงที่ทำสิ่งที่ถูกต้องได้ AFAICT, Terminal.app ขาดลำดับรีเซ็ตและคนหันไปไร้สาระทอม-hackery จะตัดรอบที่

เป้าหมายสุดท้ายของฉันที่นี่คือการresetทำงานเหมือนกันไม่ว่าฉันจะทำงานบน OS X หรือ Linux ทำงานในพื้นที่หรือจากระยะไกลผ่าน SSH (ฉันไม่ต้องการที่จะพยายามจำสิ่งที่และมันมีประโยชน์ที่จะทำreset && command-that-outputs-a-bunchและมีงานขึ้น) Terminal.app และ iTerm โยนประแจในแผนนี้โดยการใช้งานไม่resetถูกต้อง

ซึ่งหมายความว่าการเอาชนะอย่างง่ายresetนั้นไม่ได้เป็นอย่างนั้น: ถ้าฉันใช้เครื่องลีนุกซ์, มันต้องรู้ว่าฉันใช้gnome-terminalหรือ iTerm เพื่อส่งลำดับการหลบหนีที่ถูกต้องหรือไม่

มีวิธีใด ๆ (แม้ว่าฉันต้องการioctl) เพื่อขอให้ขั้วสิ่งที่มันจริงๆคืออะไร?

¹สำหรับวัตถุประสงค์ของคำถามนี้การรีเซ็ตควรล้างหน้าจอรีเซ็ตเคอร์เซอร์และล้างบัฟเฟอร์การเลื่อนกลับ


นี่เป็นฟีเจอร์ไม่ใช่ข้อผิดพลาดหรืออย่างนั้นพวกเขาก็พูด จะเกิดอะไรขึ้นถ้าคุณเปิดTerminal.appการตั้งค่าแท็บเทอร์มินัลและตั้งค่าบรรทัดการเลื่อนเป็น 0 นั่นเป็นการปิดการใช้งานข้อความใด ๆ และทั้งหมดด้านบนบรรทัดปัจจุบันหรือเพียงแค่เหนือสิ่งอื่นใดด้านบนของหน้าจอ ฉันรู้ว่ามันไม่ใช่สิ่งที่คุณขอคุ้มค่ากับการยิง
nitro2k01

@ nitro2k01: ฉันไม่แน่ใจว่าจะสำเร็จได้อย่างไร ฉันต้องการ scrollback ฉันแค่ต้องการที่จะสามารถล้างมันได้ในตอนนี้และควรเลือกด้วยresetเพราะนั่นคือสิ่งที่นิ้วมือของฉันรู้
Thanatos

สำหรับปัญหา“ รีเซ็ต” ของคุณ: เพื่อชี้แจงคุณคาดหวังว่าresetคำสั่งให้ล้างเนื้อหาการเลื่อนกลับของเทอร์มินัลอีมูเลเตอร์ แต่ไม่รับประกันว่าจะทำเช่นนั้นเพราะการเลื่อนกลับเป็นคุณสมบัติเฉพาะเทอร์มินัลอีมูเลเตอร์ ส่วนหนึ่งของอาคาร อย่างไรก็ตามเทอร์มิรองรับการขยายตัวของเอ็ด (ลบใน Display) ESC [ 3 Jลำดับหนีเพื่อลบเลื่อนกลับ คุณสามารถล้างหน้าจอแล้วใช้สิ่งนั้นเช่นreset && printf '\e[3J’
Chris Page

ดูคำตอบของฉันที่นี่apple.stackexchange.com/a/113168/6883สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการลบในส่วนขยายการแสดงผล
Chris Page

@ChrisPage: ฉันรู้ว่าเทอร์มินัลเป็นสิ่งที่แปลก แต่ถ้าคุณประกาศว่าตัวเองเป็นxterm(ผ่านTERM=xterm) ฉันคาดหวังว่าคุณจะเลียนแบบ superset ของ XTerm ซึ่งจะเคลียร์ scrollback เมื่อรีเซ็ต (เหมือนกับว่าคุณส่งลำดับการหลบหนีสำหรับ "สีน้ำเงิน" คุณคาดหวังว่าจะเป็นสีน้ำเงิน) ได้รับ xterm ของฉันบอกฉันว่าErase is backspace.ซึ่งฉันรู้สึกขอบคุณที่ไม่มีสิ่งใดทำ; มันน่ารำคาญมาก
Thanatos

คำตอบ:


10

$TERM_PROGRAMใช้

iTerm ชุดมันไปiTerm.appและ Terminal.app Apple_Terminalไป


เฮ้โอเคดีกว่าแฮ็คของฉันอย่างชัดเจน +1 :) แฮ็คควรทำงานกับเทอร์มินัลอีมูเลเตอร์ใด ๆ ไม่ใช่แค่สองตัว
terdon

ไม่มีวิธีเดียวในการตรวจจับตัวจำลองเทอร์มินัลทั้งหมด สำหรับ xterm คุณสามารถตรวจสอบตัวแปร $ XTERM_VERSION ได้ ที่จะดูแลสิ่งที่น่าจะเป็นตัวเลียนแบบสามยอดนิยมใน OS X
Chris Page

ยอมรับสิ่งนี้เพราะเป็นการเริ่มต้นที่ดี น่าเสียดายที่มันไม่ง่ายนักเนื่องจากตัวแปรนี้ไม่สามารถใช้งานได้ในเซสชัน SSH ฉันสงสัยว่ามีการกำหนดค่าที่ฉันสามารถแก้ไขเพื่อส่งต่อได้
Thanatos

1
@Thanatos sshd_config's AcceptEnvอาจ เนื่องจากสิ่งนี้ (เชลล์ของคุณทำงานบนโฮสต์ที่แตกต่างจากที่เทอร์มินัลของคุณรัน) เป็นข้อมูลที่สำคัญมากมันควรเป็นส่วนหนึ่งของคำถาม
Daniel Beck

@DanielBeck: มันไม่ได้เป็นอย่างนั้น ฉันต้องการทำสิ่งเดียวกันทั้งในและนอกสถานที่ สิ่งที่ฉันกำลังทำอยู่ก็คือการพิมพ์ "รีเซ็ต" ลงในเทอร์มินัลทำให้เกิดการรีเซ็ตเทอร์มินัลไม่ว่าฉันจะใช้ OS X หรือ Linux ทำงานในพื้นที่หรือระยะไกลก็ตาม ฉันได้แก้ไขสิ่งนี้ลงในคำถาม
Thanatos

1

$TERMไม่มีอะไรเกี่ยวข้องกับเทอร์มินัลอีมูเลเตอร์ที่กำลังทำงานอยู่มันเป็นเพียงเทอร์มินัลเริ่มต้นของคุณและสามารถตั้งค่าเป็นอะไรก็ได้ ในการรับชื่อของเทอร์มินัลอีมูเลเตอร์ที่คุณกำลังใช้งานคุณสามารถใช้psเพื่อรับ PID ของกระบวนการพาเรนต์ของเชลล์ปัจจุบันของคุณ

หมายเหตุ: ข้อมูลต่อไปนี้จะล้มเหลวบน OSX แต่ควรใช้งานได้กับ Linux

$$หมายเลขผลิตภัณฑ์ของกระบวนการเปลือกปัจจุบันของคุณ จากตรงนั้นคุณสามารถใช้psเพื่อแสดงแผนผังกระบวนการและพิมพ์ PID ของพาเรนต์ของเซสชันเชลล์ปัจจุบันของคุณ:

ps -axjf | awk -v pid=$$ '($2==pid){print $1}'

จากนั้นคุณสามารถส่ง PID นั้นpsและบอกให้พิมพ์ชื่อคำสั่ง:

ps -o comm=  $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}')

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

ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}'

นี่คือสิ่งที่ฉันได้รับในระบบของฉันโดยใช้เทอร์มินัลที่แตกต่างกัน:

  1. terminator

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/bin/x-terminal-emulator
    
  2. gnome-terminal

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/lib/gnome-terminal/gnome-terminal-server
    
  3. xterm

    $ ps --no-headers $(ps axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    xterm
    

ใช้งานไม่ได้กับ OS X:ps: illegal option -- f
Daniel Beck

@DanielBeck ยี้สไตล์ BSD ขอบคุณ คุณลองอีกครั้งด้วยรุ่นที่อัปเดตหรือไม่ เพิ่ม-ก่อนที่ตัวเลือกควรจะทำงานตาม man psOSX
terdon

ดีกว่า แต่ก็ยังไม่ทำงาน รูปแบบเอาต์พุตแตกต่างกัน (PID คือ$2, PPID คือ$3) และกระบวนการหลักของเชลล์อาจเป็นlogin(ขึ้นอยู่กับการกำหนดค่า Terminal) โดยมีพารามิเตอร์ที่แตกต่างกัน อย่างไรก็ตามของTerminalการปกครองคือ --no-headersไม่มีอยู่คุณต้องการบางสิ่งเช่นtail -n1นี้ และตั้งแต่กระบวนการทั้งหมดที่มี UI ที่มีการโต้แย้ง-psn_0_... , awk '{print $NF}'ไม่ทำงานอย่างใดอย่างหนึ่ง
Daniel Beck

@DanielBeck ดี shucks แล้ว ตกลงขอบคุณฉันจะทำให้ชัดเจนว่าล้มเหลวใน OSX
terdon

โปรดทราบว่านี่ใช้งานได้ในพื้นที่เท่านั้น คุณไม่สามารถใช้วิธีนี้เพื่อค้นหาว่าตัวจำลองเทอร์มินัลใดกำลังใช้งานบนไคลเอนต์ระยะไกล คำตอบที่ดีที่สุดคือการค้นหาตัวแปรเช่น $ TERM_PROGRAM (ดังที่ได้กล่าวไว้ในคำตอบของ @ DanielBeck) และ $ XTERM_VERSION เพื่ออนุมานแอปพลิเคชันอีมูเลเตอร์
Chris Page

0

นี่เป็นวิธีพกพาเพื่อรับชื่อหรือเส้นทางของกระบวนการหลัก:

iTerm 2:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
/Applications/iTerm.app/Contents/MacOS/iTerm

gnome-terminal ใน Ubuntu:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
gnome-terminal

Terminal.app:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
login

โปรดทราบว่าถ้า Terminal.app ถูกตั้งค่าให้เปิดเชลล์ใหม่ด้วยเชลล์ล็อกอินเริ่มต้นกระบวนการหลักของเชลล์คือloginไม่ใช่เทอร์มินัล

commคอลัมน์เป็นเส้นทางที่เต็มรูปแบบของคำสั่งใน OS X และชื่อคำสั่งตัดออกไป 15 ตัวอักษรในการดำเนินงาน procps ในลินุกซ์


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