Cách phân phối / vỏ bất khả tri tốt nhất để đặt các biến môi trường là gì?


31

Câu hỏi nói lên tất cả. Tôi hiện đang sử dụng Arch Linux và zsh, nhưng tôi muốn một giải pháp (tối thiểu) hoạt động cả trên VT và trong xterms và (hy vọng, tốt nhất là) sẽ tiếp tục hoạt động nếu tôi chuyển đổi distro hoặc shell.

Tôi đã nghe những câu trả lời khác nhau cho câu hỏi này trong các tài liệu khác nhau. Ubuntu nói "sử dụng .pam_en môi trường". Tôi nghĩ trong Arch những gì họ đề nghị phụ thuộc vào vỏ của bạn. Hiện tại tôi đặt mọi thứ vào .profile và nếu shell không có nguồn vì lý do nào đó (ví dụ: bash nếu .bash_profile tồn tại), tôi sẽ ghi đè bằng cách tự tìm nguồn cung ứng. Nhưng có vẻ như phải có một cách tốt hơn.


2
Điều này không có gì để làm với distro và mọi thứ để làm với shell. Không chắc chắn có một cách di động để làm điều đó, mặc dù.
Joseph R.

Hừm. Tuyệt vời .
strugee

Câu trả lời:


29

Thật không may, không có vị trí di động đầy đủ để đặt các biến môi trường. Hai tệp gần nhất là ~/.profilevị trí truyền thống và hoạt động tốt trên nhiều thiết lập, và ~/.pam_environment, một sự thay thế hiện đại, phổ biến nhưng có giới hạn.

Đặt gì vào ~/.pam_environment

Tệp ~/.pam_environmentđược đọc bởi tất cả các phương thức đăng nhập sử dụng PAM và đã bật tệp này. Điều này bao gồm hầu hết các hệ thống Linux hiện nay.

Ưu điểm chính của ~/.pam_environmentnó là (khi được bật) nó được đọc trước khi trình bao của người dùng bắt đầu, do đó, nó hoạt động bất kể loại phiên, vỏ đăng nhập và các phức tạp khác. Nó thậm chí hoạt động cho các thông tin đăng nhập không tương tác như su -c somecommandssh somecommand.

Hạn chế chính ~/.pam_environmentlà bạn chỉ có thể đặt các bài tập đơn giản ở đó, không phải cú pháp shell phức tạp. Cú pháp của tập tin này như sau.

  • Các tập tin được phân tích cú pháp theo từng dòng.
  • Khoảng trắng hàng đầu được bỏ qua.
  • Bạn có thể tùy ý bắt đầu các dòng với exportvà một khoảng trắng (không phải là một tab, đi hình).
  • Sau đó, mỗi dòng phải có dạng VAR=VALUEtrong đó VAR bao gồm các chữ cái, chữ số và dấu gạch dưới.
  • # bắt đầu một bình luận, nó không thể xuất hiện trong một giá trị.
  • Nếu VALUE bắt đầu bằng 'hoặc "và chứa một trích dẫn giống hệt nhau, thì VAR được đặt thành chuỗi giữa các trích dẫn (mọi thứ sau khi trích dẫn thứ hai bị bỏ qua). Nếu không, VAR được đặt thành chuỗi sau =dấu.
  • Nếu không có =, biến được loại bỏ khỏi môi trường.

Vì vậy, về mặt tích cực, ~/.pam_environmentlàm việc trong một loạt các trường hợp. Mặt khác, bạn không thể có bất kỳ cài đặt động nào, chẳng hạn như giá trị của biến trên một biến khác (ví dụ: thêm thư mục vào PATH) hoặc sử dụng đầu ra của lệnh (ví dụ: kiểm tra nếu có thư mục hoặc chương trình) và một số các ký tự ( #'", dòng mới) là không thể hoặc rắc rối để đưa vào giá trị.

Đặt gì vào ~/.profile

Tập tin này nên có cú pháp sh xách tay (POSIX). Chỉ sử dụng các phần mở rộng ksh hoặc bash (mảng [[ … ]], v.v.) nếu bạn biết rằng hệ thống của bạn có các shell này /bin/sh.

Tập tin này có thể được đọc bởi các tập lệnh trong các ứng dụng tự động, vì vậy nó không nên gọi các chương trình tạo ra bất kỳ đầu ra hoặc cuộc gọi nào exec. Nếu bạn muốn làm điều đó trên thông tin đăng nhập ở chế độ văn bản, chỉ làm điều đó cho các vỏ tương tác. Thí dụ:

case $- in *i*)
  # Display a message if I have new mail
  if mail -e; then echo 'You have new mail'; fi
  # If zsh is available, and this looks like a text-mode login, run zsh
  case "`ps $PPID` " in
    *" login "*)
      if type zsh >/dev/null 2>/dev/null; then exec zsh; fi;;
  esac
esac

Đây là một ví dụ về việc sử dụng /bin/shlàm vỏ đăng nhập của bạn và chuyển sang hệ vỏ yêu thích của bạn. Xem thêm cách tôi có thể sử dụng bash làm vỏ đăng nhập của mình khi sysadmin của tôi từ chối để tôi thay đổi

Khi ~/.profilekhông đọc được đăng nhập phi đồ họa?

Shell đăng nhập khác nhau đọc các tập tin khác nhau.

Nếu vỏ đăng nhập của bạn là bash

Bash đọc ~/.bash_loginhoặc ~/.bash_profilenếu chúng tồn tại thay vì ~/.profile. Ngoài ra bash không đọc ~/.bashrctrong vỏ đăng nhập ngay cả khi nó tương tác. Để không bao giờ phải nhớ những quirks này một lần nữa, hãy tạo một ~/.bash_profilevới hai dòng sau:

. ~/.profile
case $- in *i*) . ~/.bashrc;; esac

Xem thêm Tập tin thiết lập nào sẽ được sử dụng để thiết lập các biến môi trường với bash?

Nếu vỏ đăng nhập của bạn là zsh

Zsh đọc ~/.zprofile~/.zlogin, nhưng không ~/.profile. Zsh có một cú pháp khác với sh, nhưng có thể đọc ~/.profileở chế độ mô phỏng sh. Bạn có thể sử dụng điều này cho ~/.zprofile:

emulate sh -c '. ~/.profile'

Xem thêm Zsh không nhấn ~ / .profile

Nếu shell đăng nhập của bạn là một số shell khác

Bạn không thể làm gì nhiều ở đó, chỉ sử dụng /bin/shlàm vỏ đăng nhập và vỏ yêu thích của bạn (chẳng hạn như cá) làm vỏ tương tác. Đó là những gì tôi làm với zsh. Xem ở trên để biết ví dụ về việc gọi một shell khác từ ~/.profile.

Lệnh từ xa

Khi gọi một lệnh từ xa mà không đi qua một vỏ tương tác, không phải tất cả các shell đều đọc một tệp khởi động.

Ksh đọc tệp được chỉ định bởi ENVbiến, nếu bạn quản lý để vượt qua nó.

Bash đọc ~/.bashrcnếu nó không tương tác (!) Và quá trình cha của nó được gọi là rshdhoặc sshd. Vì vậy, bạn có thể bắt đầu ~/.bashrcvới

if [[ $- != *i* ]]; then
  . ~/.profile
  return
fi

Zsh luôn đọc ~/.zshenvkhi nó bắt đầu. Hãy thận trọng, vì điều này được đọc bởi mọi phiên bản của zsh, ngay cả khi nó là một nhánh con nơi bạn đã đặt các biến khác. Nếu zsh là vỏ đăng nhập của bạn và bạn muốn sử dụng nó để chỉ đặt các biến cho các lệnh từ xa, hãy sử dụng bộ bảo vệ: đặt một số biến trong ~/.profile, chẳng hạn như MY_ENVIRONMENT_HAS_BEEN_SET=yes, và kiểm tra bảo vệ này trước khi đọc ~/.profile.

if [[ -z $MY_ENVIRONMENT_HAS_BEEN_SET ]]; then emulate sh -c '~/.profile'; fi

Các trường hợp đăng nhập đồ họa

Nhiều bản phân phối, trình quản lý hiển thị và môi trường máy tính để bàn sắp xếp để chạy ~/.profile, bằng cách tìm nguồn cung ứng rõ ràng từ các tập lệnh khởi động hoặc bằng cách chạy shell đăng nhập.

Thật không may, không có phương pháp chung để xử lý các kết hợp distro / DM / DE mà ~/.profilekhông đọc được.

Nếu bạn sử dụng một phiên truyền thống bắt đầu bởi ~/.xsession, đây là nơi bạn nên đặt các biến môi trường của mình; làm điều đó bằng cách tìm nguồn cung ứng ~/.profile(tức là . ~/.profile). Lưu ý rằng trong một số thiết lập, tập lệnh khởi động môi trường máy tính để bàn sẽ lấy ~/.profilelại nguồn .


những gì case $- in *i*)làm gì?
qodeninja

2
@qodeninja Thực hiện các hướng dẫn sau (cho đến khi khớp ;;hoặc esac) nếu $-khớp với mẫu *i*, tức là nếu $-i, tức là nếu vỏ tương tác.
Gilles 'SO- ngừng trở nên xấu xa'

$-là một chuỗi các tùy chọn shell hiện được đặt. (thích set -x). icó nghĩa là vỏ tương tác.
Peter Cordes

Bạn có thể chỉ cần một nguồn chung, nói ~/.config/env, ngay cả khi không có mô phỏng?
Kevin Scos

1
@ StéphaneChazelas Đó là một quan điểm thuần túy. Tôi vẫn .profiletuân thủ các vỏ Bourne khá cũ, nhưng tôi nhận ra rằng một số người không quan tâm. Tôi không có gì chống lại mọi người khi cho rằng sh = bash cho các tệp của riêng họ, tôi chỉ quan tâm nếu họ xuất bản #!/bin/shtập lệnh sử dụng các tính năng bash.
Gilles 'SO- ngừng trở nên xấu xa'

4

Theo như tôi biết thì không tồn tại tiêu chuẩn phân phối và vỏ không biết cách thiết lập các biến môi trường.

Các tiêu chuẩn phổ biến nhất và thực tế dường như là /etc/profile~/.profile. Phổ biến thứ hai dường như là /etc/environment~/.pam_environment.

Dường như với tôi rằng tất cả các tài liệu mà tôi tìm thấy bạn cũng đã được tìm thấy. Tôi liệt kê chúng ở đây dù sao cho các độc giả khác.

  • Debian khuyến nghị /etc/profile~/.profile( liên kết ).
  • Ubuntu khuyến nghị /etc/environment~/.pam_environment( liên kết ).
  • Arch Linux đề cập, trong số những người khác, /etc/profile/etc/environment( liên kết ).

Phần thưởng: một văn bản đặt câu hỏi về việc sử dụng và / hoặc sử dụng sai /etc/environmenttrong debian ( liên kết , bản cập nhật mới nhất 2008).


Bất kể tập tin bạn sử dụng là gì, bạn vẫn sẽ gặp phải cú pháp không tương thích giữa các shell khác nhau.
Joseph R.

1
@JosephR. Không phải hầu hết các vỏ giữ tương thích ngược với sh? Chừng nào bạn còn gắn bó với POSIX, tôi sẽ nghĩ bạn sẽ ổn thôi ...
evilsoup

1
AFAIK bạn không thể gán biến cshvà bạn bè theo cách POSIX (bạn cần một cái gì đó giống như sethoặc setenv)
Joseph R.

0

Tôi đã thêm đoạn script sau ~ / bin / agninto_setenv:

#!/bin/csh -f
set args = ($*)
if ($#args == 1) then
   echo "export $args[1]="
   exit 0
endif

if ($#args == 2) then
   if ("$args[1]" =~ *csh*) then 
      echo "setenv $args[2]"
      exit 0
   else
      echo "export $args[1]=$args[2]"
      exit 0
   endif
endif

echo "setenv $args[2] $args[3]"

Và trong ~ / .perl-homedir tôi sử dụng:

eval `${HOME}/bin/agnostic_setenv $shell PERL_HOMEDIR 0`

Một tập lệnh tương tự cho agnellect_unsetenv:

#!/bin/csh -f
set args = ($*)
if ($#args == 1) then
   echo "export $args[1]"
   exit 0
endif

echo "unsetenv $args[2]"
exit 0
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.