หน้าจอ GNU จะไม่สืบทอด PATH ของฉันที่ 10.5.8


11

ฉันใช้หน้าจอเป็นประจำทุกวันสำหรับความต้องการของเครื่องและฉันมีความสุขมากกับมัน เมื่อเร็ว ๆ นี้ แต่ผมทำบางอย่างเพื่อการปรับปรุงแฟ้มการกำหนดค่าทุบตีของฉันและฉันสังเกตเห็นว่าผมได้รับการตั้งค่าต่าง ๆPATHองค์ประกอบ ( PATH, MANPATH, INFOPATHฯลฯ ) ในสถานที่ 2 แห่ง .bash_profileผมปรับเปลี่ยนไฟล์ที่จะเป็นสิ่งที่พวกเขาควรจะเป็นและตอนนี้ทั้งหมดของตัวแปรสภาพแวดล้อมของฉันได้รับการตั้งครั้งเดียวใน นี่คือปัญหาของฉัน

เห็นได้ชัดว่าเหตุผลที่ฉันตั้งค่าพวกเขาในสองสถานที่เป็นเพราะหน้าจอ หน้าจอปรากฏขึ้นเพื่อดำเนินการเท่านั้น.bashrcและไม่ได้รับมรดกPATHตัวแปรสภาพแวดล้อมอื่น ๆของฉันหรืออย่างถูกต้องจากเปลือก bash ดั้งเดิมของฉัน เพราะเพียงดำเนินการ.bashrcและตอนนี้ฉันตั้งค่าตัวแปรของฉันในเพียงฉันได้รับไม่สมบูรณ์.bash_profilePATH

คำถามของฉันคือการทำให้ตัวแปรสภาพแวดล้อมของฉันเข้าสู่หน้าจอโดยไม่ต้องทำซ้ำ การอ่านผ่านBashเอกสารดูเหมือนจะบ่งบอกว่ามันอาจเป็นชนิดของเชลล์ที่หน้าจอใช้ในการเข้าสู่ระบบนั่นคือเชลล์แบบโต้ตอบที่ไม่ใช่การเข้าสู่ระบบแต่ฉันไม่สามารถหาวิธีบังคับให้หน้าจอใช้เชลล์ชนิดใดชนิดหนึ่งเท่านั้น -s /bin/bashเปลือกใช้ผ่านทาง

คุณสามารถอ่าน config ไฟล์ของฉันที่หน้า GitHub ของฉัน นี่คือการกระทำการกระทำที่หน้าจอยากจน

แก้ไข:ฉันใช้Screen version 4.00.03 (FAU) 23-Oct-06และฉันมักจะเรียกใช้โดยscreen -h 50000

แก้ไข:ตอนนี้ฉันสามารถทดสอบบน Cygwin ( CYGWIN_NT-5.1 1.7.1(0.218/5/3) i686, Screen version 4.00.03 (FAU) 23-Oct-06) และมันแสดงพฤติกรรมที่แตกต่างจากบน Mac ของฉัน

พฤติกรรมเฉพาะที่ฉันค้นพบตอนนี้คือใน Cygwin การเปลี่ยนแปลงที่ฉันทำPATHใน. bash_profile นั้นซ้ำกันเมื่อเข้าสู่หน้าจอจากนั้นการสร้างหน้าต่างหน้าจอที่ต่อเนื่องกันจะไม่ทำซ้ำเส้นทาง แต่ทำซ้ำ. bash_profile

เพื่อแสดงพฤติกรรมที่ฉันกำลังพูดถึง:

เอาท์พุทจากสถานีสด:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

เอาต์พุตจากการร้องขอหน้าจอแรก:

[~]$ screen -h 50000 -s -/bin/bash

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

การโทรครั้งต่อไปที่C-a c:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

คุณสามารถเห็น


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

คำตอบ:


16

หน้าจอและตัวแปรสภาพแวดล้อม

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

สมมติว่าการตั้งค่าเชลล์ของคุณหรือการกำหนดค่าหน้าจอจะไม่เปลี่ยนแปลงตัวแปรที่ชื่อว่าFOOBAR (น่าจะเป็นทั้งหมด หากคุณเริ่มต้นเซสชั่นด้วยFOOBAR=foo screenแล้วเปลือกหอยทั้งหมดที่สร้างขึ้นในเซสชั่นที่จะมีตัวแปรสภาพแวดล้อมชื่อFoobarfooที่มีค่าของ

สิ่งต่าง ๆ มีความซับซ้อนมากขึ้นสำหรับตัวแปรที่หน้าจอหรือเปลือกของคุณอาจแก้ไข

การตั้งค่าที่หายไปเมื่อใช้หน้าจอ

ล็อกอินเชลล์

หากคุณพบว่าการตั้งค่าบางอย่างขาดหายไปในเชลล์ที่เริ่มต้นด้วยหน้าจออาจเป็นเพราะเชลล์ของคุณได้รับการกำหนดค่าให้อัปเดตการตั้งค่าเหล่านั้นสำหรับเชลล์ 'ล็อกอิน' เท่านั้น เปลือกหอยส่วนใหญ่เข้าใจการประชุมพิเศษ (ใน C: **argv == '-') ที่หน้าจอสามารถกำหนดค่าให้ใช้

ตามเอกสารหน้าจอ :

คำสั่งเชลล์

ตั้งค่าคำสั่งที่จะใช้ในการสร้างเปลือกใหม่ สิ่งนี้จะแทนที่ค่าของตัวแปรสภาพแวดล้อม $ SHELL สิ่งนี้มีประโยชน์หากคุณต้องการเรียกใช้โปรแกรมเสริมซึ่งคาดว่าจะรันโปรแกรมเฉพาะใน $ SHELL หากคำสั่งเริ่มต้นด้วยอักขระ '-' เชลล์จะเริ่มต้นเป็น login-shell

หากต้องการให้เชลล์เริ่มต้นหน้าจอเป็นเชลล์สำหรับเข้าสู่ระบบให้เริ่มต้นหน้าจอด้วยscreen -s -/bin/bashหรือเพิ่มบรรทัดนี้ใน.screenrc:

shell -/bin/bash

ปรับเส้นทางให้กับเชลล์ที่คุณใช้งานอยู่

การกำหนดค่าหน้าจอ

ตัวแปรสภาพแวดล้อมที่ขาดหายไปหรืออาจเป็นเพราะsetenvและunsetenvคำสั่งในไฟล์กำหนดค่าหน้าจอ คุณจะต้องตรวจสอบทั้ง.screenrcในไดเรกทอรีบ้านของคุณและแล้วแต่จำนวนใดแฟ้มสะสมของคุณของหน้าจอที่ใช้เป็นระบบ screenrc '(คุณอาจลองคำสั่งเช่นstrings "$(which screen)" | fgrep -i screenrcการหาชื่อพา ธ ที่มีการกำหนดค่าที่รวบรวมเวลามันเป็นเรื่องปกติ/ etc / screenrcสำหรับหน้าจอที่ติดตั้งระบบการติดตั้งส่วนเสริมอาจใช้ชื่อพา ธ อื่น คุณสามารถใช้SCREENRC=/dev/null SYSSCREENRC=/dev/null screenเพื่อหลีกเลี่ยงไฟล์การตั้งค่าเหล่านี้ได้ชั่วคราว แต่มีตัวเลือกเวลารวบรวมที่ป้องกันการใช้งานSYSSCREENRCอย่างมีประสิทธิภาพ (สมมุติว่าผู้ดูแลระบบสามารถบังคับให้ตั้งค่าเริ่มต้นเล็กน้อย)

ตั้งค่าซ้ำเมื่อใช้หน้าจอ

เป็นเรื่องปกติที่จะเพิ่มรายการลงในตัวแปรสภาพแวดล้อมเช่นPATHในไฟล์การกำหนดค่าของเชลล์เพื่อให้ค่าที่อัปเดตพร้อมใช้งานในเซสชันเชลล์ปกติ (เช่นxtermหรือเทอร์มินัล windows อื่น ๆ เซสชันคอนโซล ฯลฯ ) หากมีการเพิ่มรายการดังกล่าวในการกำหนดค่าต่อเชลล์ของเชลล์ (หรือหากคุณใช้การ-/path/to/shellตั้งค่าที่อธิบายไว้ข้างต้นในการกำหนดค่าต่อการเข้าสู่ระบบเชลล์) จากนั้นเชลล์ที่เริ่มต้นด้วยหน้าจออาจมีสำเนาหลายรายการ

กลยุทธ์หนึ่งที่จะหลีกเลี่ยงปัญหานี้คือการวางเพิ่มเติมทั้งหมดกับตัวแปรเช่นเส้นทางในการกำหนดค่าต่อการเข้าสู่ระบบของเปลือกของคุณและหลีกเลี่ยงการใช้-/path/to/shellการตั้งค่าเปลือกหน้าจอ

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

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

การวินิจฉัย

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

ตรวจสอบค่าปัจจุบันในเชลล์เริ่มต้นของคุณ:

echo "$PATH"

ตรวจสอบว่าเชลล์ปรับเปลี่ยนค่าได้อย่างไรเมื่อสร้างเชลล์ย่อย:

/bin/bash -c 'echo "$PATH"'

ตรวจสอบวิธีที่เชลล์ปรับเปลี่ยนค่าเมื่อสร้างเชลล์ย่อย 'ล็อกอิน':

perl -e '$s=shift;exec {$s} "-$s", @ARGV or die "unable to start shell"' /bin/bash
echo "$PATH"
exit

ตรวจสอบว่าหน้าจอแก้ไขค่า:

printf '#!/bin/sh\nl=/tmp/echo-var.log;rm -f "$l"; echo $PATH >"$l"' >/tmp/echo-var &&
chmod a+x /tmp/echo-var &&
screen -s /tmp/echo-var &&
cat /tmp/echo-var.log

วิธีนี้ช่วยแก้ไขปัญหาของฉันได้ น่าเสียดายที่มันไม่ได้ไปอย่างเต็มรูปแบบ ตอนนี้หน้าจอทำงานได้ดีscreen -s -/bin/bashแต่ก็ไม่ได้ทำงานเหมือนที่ฉันคาดหวังว่ามันจะทำงานภายใต้ Cygwin ในเครื่องทำงานของฉัน บนเครื่องนั้นฉันทำงานscreen -h 50000และมันก็สืบทอดPATHโดยที่ฉันไม่ได้จัดหาไฟล์อีกครั้ง สิ่งนี้จะทำงานทั้งสองครั้งทุกครั้งที่ฉันเปิดหน้าต่างใหม่
ทิม Visher

สภาพแวดล้อมของกระบวนการหน้าจอควรสืบทอดโดยลูก ๆ ของมันเสมอ (ยกเว้นสิ่งที่ต้องการระยะที่มันอาจจะแทนที่) ลองFOOBAR=baz screenและตรวจสอบecho $FOOBARในหน้าต่างเปลือกจากและscreen screen -s -/bin/bashทั้งสองรูปแบบที่ควรจะมี=FOOBAR bazหากคุณPATHกำลังแก้ไขคุณจะต้องติดตามสิ่งที่กำลังทำอยู่ ลองSYSSCREENRC=/dev/null SCREENRC=/dev/null screenถ้าที่ช่วยให้คุณPATHผ่านแล้วมันอาจจะเป็นsetenv PATHในหรือ/etc/screenrc ~/.screenrcไม่อย่างนั้นมันเป็นสิ่งที่คุณ.bashrcทำอยู่
Chris Johnsen

ฉันเขียน / เติมคำตอบของฉันจำนวนมาก
Chris Johnsen

2

ครั้งสุดท้ายที่ฉันเห็นปัญหาที่คล้ายกันฉันแก้ไขได้โดยใช้screen -lเมื่อหน้าจอเริ่มต้น

คุณสามารถใช้-lตัวเลือกนี้เมื่อscreenเปิดใช้งาน(เปิดโหมดเข้าสู่ระบบควบคุมด้วยคำสั่งdefloginและloginใน.screenrc) เพื่อตั้งค่าว่าหน้าจอควรเข้าสู่ระบบหน้าต่างตามค่าเริ่มต้นหรือไม่ (เพิ่ม / ลบรายการ / etc / utmp)

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

ฉันไม่ต้องการ-lโหมดในหน้าจอเริ่มต้นของ Debian Lenny (v4.0.3); ดูเหมือนว่าจะเป็นโดยค่าเริ่มต้น ฉัน~/.profileและ~/.bashrcได้รับการอ่านอย่างถูกต้อง คุณเป็นscreenอย่างไรบ้าง คุณใช้เวอร์ชั่นอะไร


ภายใต้ทฤษฎีนี้ไม่screen -lnควรเรียกใช้ของฉันและมันก็ยังคงได้รับ ลองใช้แฟล็ก แต่นี่อาจไม่ใช่คำตอบที่ถูก จะออกจากที่นี่สักครู่ ~/.profile-l
ต้มตุ๋น quixote

ดูเหมือนว่า-lจะควบคุมว่าscreenจะเพิ่มรายการลงในutmpไฟล์หรือไม่ไม่ว่าจะเรียกใช้เชลล์ใหม่พร้อมตัว-lเลือกของตนเองหรือใช้ exec- -with- -prefix custom
Chris Johnsen

2

ปัญหาอยู่ที่พฤติกรรมของ launchd บน Leopard ดูรายงานข้อผิดพลาด MacPorts นี้สำหรับหน้าจอบน Leopard เพื่อดูว่าทำไมมันถึงไม่ได้รับการแก้ไขจนกว่าคุณจะสามารถเปิดตัว Snowd's backd

https://trac.macports.org/ticket/18235#comment:26


1

ไม่มีอะไรผิดปกติในการจัดหา. bashrc ของคุณจากภายใน. bash_profile หากคุณใช้เครื่องของคุณในพื้นที่. bash_profile ของคุณโดยส่วนใหญ่แล้วจะเป็นแหล่งที่มาเฉพาะเมื่อคุณเข้าสู่ระบบครั้งแรกของคุณ

ฉันจัดระเบียบไฟล์ของฉันเพื่อที่ว่าถ้าฉันต้องการสิ่งที่จะทำก็ต่อเมื่อฉันเข้าสู่ระบบฉันใส่ข้อมูลใน. bash_profile และสำหรับทุกสิ่งที่ฉันใส่ไว้ใน. bashrc PATH คือสิ่งหนึ่งที่ฉันใส่ไว้ใน. bashrc ของฉันและฉันได้จัดหา. bashrc ใน. bash_profile ของฉัน


คุณจะโพสต์.bashrcและ.bash_profileไฟล์ของคุณที่อื่นเพื่อให้ฉันเห็นได้หรือไม่? ปัญหาที่ฉันพบขณะทำสิ่งที่คล้ายกันคือมันPATHจะเพิ่มขึ้นทุกครั้งที่ฉันจะสร้างอินสแตนซ์ของหน้าจอใหม่เพราะมันจะสืบทอดมรดกเก่าPATHแล้วเพิ่มทุกอย่างอีกครั้งอีกครั้ง
Tim Visher

ขอโทษทิมฉันไม่เห็นสิ่งนี้ ... ฉันได้เปลี่ยนสิ่งต่าง ๆ มากมายดังนั้นพวกเขาจะไม่เข้าท่า แต่นี่เป็นสิ่งที่ฉันทำ # .bash_profile ถ้า [-f ~ / .bashrc]; จากนั้น ~ / .bashrc fi จากนั้นฉันใส่ทุกอย่างไว้ใน. bashrc ยกเว้นสิ่งที่ฉันต้องการเริ่มเมื่อฉันเข้าสู่ระบบครั้งแรกซึ่งยังไปใน. bash_profile PATH ได้รับการจัดการใน. bashrc เป็นชุดของบรรทัดแทนที่จะเป็นหนึ่งนิยามพา ธ ที่ต้องการส่งออก PATH = / path / to / binaries1 มากที่สุด: $ PATH ส่งออก PATH = / path / to / binaries2: $ PATH

0

เมื่อใดก็ตามที่ฉันมีปัญหาบางอย่างเช่นที่ผมสร้างไฟล์$HOME/.debugและไฟล์ทั้งหมดที่มา / ดำเนินการในระหว่างการเข้าสู่ระบบ / ภาวนาเปลือก (เช่น~/.bashrc, ~/.bash_profile, ~/.profile, /etc/bashrcฯลฯ ) ฉันมีเป็นบรรทัดแรก

test -f $HOME/.debug && echo $HOME/.bashrc 1>&2

หรือคล้ายกัน สำหรับการดีบักเฉพาะคุณสามารถเพิ่มสิ่งต่าง ๆ เช่น

test -f $HOME/.debug && echo PATH now equals $PATH 1>&2

วิธีนี้คุณสามารถมั่นใจได้ 100% อย่างแน่นอนว่าไฟล์ใดที่มีหรือไม่มีการใช้งาน

การเปลี่ยนเส้นทางไปยัง stderr เป็นสิ่งสำคัญคุณไม่ต้องการให้บางสิ่งบางอย่างยุ่งกับ stdout ในหลาย ๆ สถานการณ์


0

คุณสามารถอยู่กับ. profile ได้เนื่องจากระบบไม่ได้แตะ bashrc (เช่นเซสชันกราฟิก) ตอนนี้คุณมีสภาพแวดล้อมที่แตกต่างกันสองชุด - หนึ่งจาก. profile และอื่น ๆ สำหรับ bash จาก. bashrc

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