Màn hình GNU sẽ không kế thừa PATH của tôi vào ngày 10.5.8


11

Tôi sử dụng màn hình hàng ngày cho nhu cầu thiết bị đầu cuối của mình và tôi khá hài lòng với nó. Gần đây, tuy nhiên, tôi thực hiện một số bản cập nhật cho các file cấu hình bash của tôi và tôi nhận thấy rằng tôi đã thiết lập khác nhau PATHcác yếu tố ( PATH, MANPATH, INFOPATH, vv) trong 2 nơi. Tôi đã sửa đổi các tệp thành đúng như những gì chúng cần và bây giờ tất cả các biến môi trường của tôi được đặt một lần vào .bash_profile. Đây là vấn đề của tôi.

Rõ ràng, lý do tôi đặt chúng ở hai nơi là vì màn hình. màn hình dường như chỉ thực thi .bashrcvà dường như không kế thừa PATHchính xác hoặc bất kỳ biến môi trường nào khác từ vỏ bash ban đầu của tôi. Bởi vì nó chỉ thực thi .bashrcvà bây giờ tôi .bash_profilechỉ đặt các biến của mình , tôi nhận được một không đầy đủ PATH.

Sau đó, câu hỏi của tôi là làm thế nào để đưa các biến môi trường của tôi vào màn hình mà không bị trùng lặp. Đọc qua các Bashtài liệu dường như chỉ ra rằng nó có thể là loại vỏ mà màn hình sử dụng để đăng nhập, tức là vỏ tương tác không đăng nhập nhưng tôi không thể tìm ra cách buộc màn hình sử dụng một loại vỏ cụ thể, chỉ Shell để sử dụng thông qua -s /bin/bash.

Bạn có thể kiểm tra các tệp cấu hình của tôi tại trang GitHub của tôi . Đây là cam kết đã phá vỡ màn hình .

EDIT: Tôi đang sử dụng Screen version 4.00.03 (FAU) 23-Oct-06và tôi có xu hướng gọi nó bằng cáchscreen -h 50000

EDIT: Bây giờ tôi đã có thể thử nghiệm điều này trên Cygwin ( CYGWIN_NT-5.1 1.7.1(0.218/5/3) i686, Screen version 4.00.03 (FAU) 23-Oct-06) và nó thể hiện hành vi khác so với trên máy Mac của tôi.

Hành vi cụ thể mà tôi đã phát hiện ra là trong Cygwin, những thay đổi mà tôi thực hiện PATHtrong .bash_profile được sao chép khi vào màn hình và sau đó tạo liên tiếp các cửa sổ màn hình không sao chép đường dẫn mà thực hiện lại nguồn .bash_profile.

Để minh họa hành vi tôi đang nói về:

Đầu ra từ một thiết bị đầu cuối mới:

...

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 ../..'

...

[~]$

Đầu ra từ lần gọi đầu tiên của màn hình:

[~]$ 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ác cuộc gọi tiếp theo tới 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 ../..'

...

[~]$

Bạn có thể thấy


Sự trùng lặp là do bạn đã cấu hình bash để thêm vô điều kiện các mục này với nó là một vỏ 'đăng nhập' và bạn đang nói với màn hình để gọi bash là một vỏ 'đăng nhập'. Tôi đã viết lại câu trả lời của mình để cố gắng giải quyết các vấn đề chung về shell, màn hình và các biến môi trường.
Chris Johnsen

Câu trả lời:


16

màn hình và biến môi trường

Theo mặc định, màn hình chuyển qua các shell của nó (và các quá trình khác) bất kỳ biến môi trường nào có khi phiên bắt đầu (nghĩa là kết nối lại không thay đổi biến môi trường nào được cung cấp cho shell mới). Nhưng vì các tệp cấu hình của cả màn hình và hệ vỏ thường thay đổi các biến môi trường, nên có nhiều nơi có thể đưa ra các thay đổi bất ngờ. Có một vài biến số, như TERM , màn hình đó hầu như luôn thay đổi, nhưng chúng thường được yêu cầu cho chức năng mà màn hình cung cấp.

Giả sử rằng cả cấu hình của vỏ của bạn cũng như cấu hình của màn hình sẽ không sửa đổi một biến có tên là FOOebar (hoàn toàn có khả năng, tất cả đều có). Nếu bạn bắt đầu một phiên với FOOBAR=foo screen, thì tất cả các shell được tạo trong phiên đó sẽ có một biến môi trường có tên là FOOebar với giá trị là foo.

Mọi thứ trở nên phức tạp hơn đối với các biến mà màn hình hoặc vỏ của bạn có thể sửa đổi.

Thiếu cài đặt khi sử dụng màn hình

Đăng nhập Shell

Nếu bạn thấy rằng một số cài đặt bị thiếu trong trình bao bắt đầu bằng màn hình , có thể là do trình bao của bạn chỉ được định cấu hình để cập nhật các cài đặt đó cho trình bao 'đăng nhập'. Hầu hết các shell đều hiểu một quy ước đặc biệt (trong C **argv == '-':) mà màn hình có thể được cấu hình để sử dụng.

Theo tài liệu trên màn hình :

lệnh shell

Đặt lệnh sẽ được sử dụng để tạo shell mới. Điều này ghi đè giá trị của biến môi trường $ SHELL. Điều này rất hữu ích nếu bạn muốn chạy một bộ tăng cường tty dự kiến ​​sẽ thực thi chương trình được chỉ định trong $ SHELL. Nếu lệnh bắt đầu bằng ký tự '-', shell sẽ được bắt đầu dưới dạng shell đăng nhập.

Để có màn hình vỏ bắt đầu như 'đăng nhập' vỏ, bắt đầu màn hình với screen -s -/bin/bash, hoặc thêm dòng này vào bạn .screenrc:

shell -/bin/bash

Điều chỉnh đường dẫn đến bất kỳ shell nào bạn đang sử dụng.

Cấu hình màn hình

Thiếu hoặc đặt lại các biến môi trường cũng có thể là do setenvunsetenvcác lệnh trong tệp cấu hình màn hình. Bạn sẽ phải kiểm tra cả .screenrc trong thư mục chính của bạn và bất kỳ tệp nào mà trình biên dịch màn hình của bạn đang sử dụng là 'system screenrc' (bạn có thể thử một lệnh như strings "$(which screen)" | fgrep -i screenrctìm tên đường dẫn được định cấu hình tại thời gian biên dịch thường là / etc / screenrc cho màn hình được cài đặt hệ thống, cài đặt bổ trợ có thể sẽ sử dụng một số tên đường dẫn khác). Bạn có thể sử dụng SCREENRC=/dev/null SYSSCREENRC=/dev/null screenđể tạm thời tránh các tệp cài đặt này, nhưng có một tùy chọn biên dịch thời gian ngăn chặn việc sử dụng hiệu quả SYSSCREENRC (có lẽ để quản trị viên hệ thống có thể buộc một chút cấu hình ban đầu).

Cài đặt trùng lặp khi sử dụng màn hình

Việc thêm các mục vào biến môi trường như PATH trong (các) tệp cấu hình của shell là khá phổ biến để giá trị cập nhật có sẵn cho các phiên shell thông thường (ví dụ: xterm hoặc các cửa sổ đầu cuối khác, phiên giao diện điều khiển, v.v.). Nếu các mục đó được thêm vào trong cấu hình per-shell của shell (hoặc, nếu bạn đang sử dụng -/path/to/shellcài đặt được mô tả ở trên, trong cấu hình shell cho mỗi lần đăng nhập) thì shell bắt đầu bằng màn hình sẽ có nhiều bản sao của các mục được thêm vào.

Một chiến lược để tránh điều này là đưa tất cả các bổ sung vào các biến như PATH vào cấu hình mỗi lần đăng nhập của trình bao của bạn và tránh sử dụng -/path/to/shellcài đặt shell với màn hình .

Một chiến lược khác là chỉ có điều kiện thêm các mục mới vào biến. Tùy thuộc vào shell, mã để làm điều này có thể hơi phức tạp, nhưng nó thường có thể được gói gọn trong một hàm shell để dễ sử dụng.

Một chiến lược khác là luôn bắt đầu với một giá trị cố định trong các tệp cấu hình của bạn. Điều này đôi khi có thể gây ra sự cố khi di chuyển tệp cấu hình của bạn từ hệ thống này sang hệ thống khác khi các giá trị mặc định có thể thay đổi đáng kể.

Chẩn đoán

Nếu bạn không thể trực tiếp phát hiện ra nơi sửa đổi cụ thể đang diễn ra, bạn có thể thử cách sau để theo dõi nơi thay đổi đang diễn ra.

Kiểm tra giá trị hiện tại trong vỏ ban đầu của bạn:

echo "$PATH"

Kiểm tra cách shell tự sửa đổi giá trị khi tạo vỏ phụ:

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

Kiểm tra cách trình bao sửa đổi giá trị khi lớp vỏ phụ 'đăng nhập' được tạo:

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

Kiểm tra cách màn hình sửa đổi giá trị:

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

Điều này giải quyết một phần vấn đề của tôi. Thật không may, nó không đi theo cách đầy đủ. Bây giờ, màn hình đang hoạt động tốt screen -s -/bin/bashnhưng nó không hoạt động như tôi mong đợi nó sẽ hoạt động theo Cygwin trên máy làm việc của tôi. Trên máy đó, tôi chạy screen -h 50000và nó chỉ đơn giản là kế thừa của tôi PATHmà không thực sự tìm nguồn cung cấp lại tệp. Điều này chạy cả hai lần tôi khởi chạy một cửa sổ mới.
Tim Visher

Môi trường của quá trình sàng lọc phải luôn được kế thừa bởi bất kỳ con nào của nó (ngoại trừ những thứ như TERM mà nó có thể ghi đè). Hãy thử FOOBAR=baz screenvà kiểm tra echo $FOOBARcác cửa sổ vỏ từ screenscreen -s -/bin/bash. Cả hai biến thể nên có FOOBAR= baz. Nếu bạn PATHđang được sửa đổi, thì bạn sẽ phải theo dõi những gì đang làm điều đó. Hãy thử SYSSCREENRC=/dev/null SCREENRC=/dev/null screen, nếu điều đó cho phép bạn PATHthông qua, thì nó có thể là setenv PATHtrong /etc/screenrchoặc ~/.screenrc. Nếu không thì đó là điều bạn .bashrcđang làm.
Chris Johnsen

Tôi đã thực hiện viết lại lớn / thêm vào câu trả lời của tôi.
Chris Johnsen

2

Lần cuối cùng tôi gặp một vấn đề tương tự, tôi đã giải quyết nó bằng cách sử dụng screen -lkhi bắt đầu màn hình.

Bạn có thể sử dụng -ltùy chọn khi gọi screen(bật chế độ đăng nhập ; cũng được điều khiển bởi các lệnh defloginlogintrong .screenrc) để đặt màn hình có nên đăng nhập cửa sổ theo mặc định hay không (thêm / xóa mục nhập / etc / utmp).

Chế độ đăng nhập được bật theo mặc định, nhưng có thể thay đổi vào thời gian biên dịch. Nếu màn hình không được biên dịch với utmp hỗ trợ, các lệnh này sẽ không khả dụng.

Tôi dường như không cần -lchế độ trong màn hình mặc định của Debian Lenny (v4.0.3); nó dường như được bật theo mặc định. Tôi ~/.profile~/.bashrcđang được đọc chính xác. Làm thế nào bạn đang gọi screen? Phiên bản nào bạn đang sử dụng?


tho theo lý thuyết này, khôngscreen -ln nên chạy của tôi , và nó vẫn được chạy. Vì vậy, hãy thử cờ, nhưng đây có lẽ không phải là câu trả lời đúng. sẽ để nó ở đây cho đến thời điểm này. ~/.profile-l
quack quixote

Dường như -lchỉ kiểm soát xem có screenthêm mục nhập vào utmptệp hay không, liệu nó có gọi trình bao mới với -ltùy chọn riêng hay sử dụng -tùy chỉnh exec-with- -prefix.
Chris Johnsen


1

Không có gì sai khi tìm nguồn cung cấp .bashrc của bạn từ bên trong .bash_profile. Nếu bạn chỉ sử dụng máy cục bộ thì .bash_profile của bạn trong hầu hết các trường hợp sẽ chỉ có nguồn gốc khi bạn đăng nhập lần đầu (rõ ràng có những lần khác nó có nguồn gốc).

Tôi sắp xếp các tệp của mình để nếu tôi muốn một cái gì đó được thực hiện chỉ khi tôi đăng nhập, tôi đưa thông tin vào .bash_profile và cho mọi thứ khác tôi đặt chúng vào .bashrc. PATH là một thứ tôi đặt trong .bashrc và tôi lấy .bashrc trong .bash_profile của tôi.


Bạn có thể thoải mái đăng các tập tin .bashrc.bash_profiletập tin của bạn ở đâu đó để tôi có thể nhìn thấy chúng? Vấn đề tôi gặp phải trong khi làm một cái gì đó tương tự là nó PATHsẽ phát triển mỗi lần tôi tạo một phiên bản màn hình mới bởi vì nó sẽ kế thừa cái cũ PATHvà sau đó thêm lại mọi thứ một lần nữa.
Tim Visher

Xin lỗi Tim, tôi đã không thấy điều này ... Tôi đã thay đổi rất nhiều thứ xung quanh để chúng không có ý nghĩa gì, nhưng về cơ bản đây là những gì tôi làm. # .bash_profile nếu [-f ~ / .bashrc]; sau đó . ~ / .bashrc fi Sau đó, tôi đặt mọi thứ khác vào .bashrc, ngoại trừ những thứ tôi muốn bắt đầu khi đăng nhập lần đầu, cũng đi vào .bash_profile. PATH được xử lý trong .bashrc như một loạt các dòng thay vì định nghĩa một con đường giống như hầu hết làm export PATH = / path / to / binaries1: $ PATH export PATH = / path / to / binaries2: $ PATH

0

Bất cứ khi nào tôi có một số vấn đề như thế nào để tạo một tập tin $HOME/.debugvà trong tất cả các tập tin nguồn gốc / thực hiện trong quá trình đăng nhập / gọi shell (ví dụ ~/.bashrc, ~/.bash_profile, ~/.profile, /etc/bashrc, vv) Tôi có như dòng đầu tiên

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

hoặc tương tự. Để gỡ lỗi cụ thể, bạn cũng có thể thêm những thứ như

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

Bằng cách này, bạn có thể hoàn toàn chắc chắn 100% những tập tin nào được sử dụng hay không.

Chuyển hướng đến thiết bị lỗi chuẩn rất quan trọng, bạn không muốn có thứ gì đó làm rối loạn thiết bị xuất chuẩn trong nhiều tình huống.


0

Bạn có thể ở lại với .profile vì hệ thống không chạm vào bashrc (như phiên đồ họa) Bây giờ bạn chỉ cần có hai bộ môi trường khác nhau - một từ .profile, khác cho bash từ .bashrc.

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.