Tôi nên xuất một biến môi trường ở đâu để tất cả các kết hợp bash / dash, tương tác / không tương tác, đăng nhập / không đăng nhập, sẽ chọn nó?


11

Đây là động lực cho câu hỏi:

Tôi đang sử dụng Ubuntu 12.04 LTS 2 với máy tính để bàn Unity. Trong tệp .bashrc của tôi, tôi nối thêm một số thư mục vào biến PATH của mình và xác định một vài biến môi trường, chẳng hạn như JAVA_HOME. Khi tôi khởi chạy ứng dụng từ thiết bị đầu cuối (chạy bash, shell mặc định của tôi), điều này hoạt động rất tốt, nhưng đối với một số phím tắt sử dụng trình khởi chạy Unity, chúng chạy các ứng dụng dường như được xác định để sử dụng #! / Bin / sh, được đặt bí danh là / bin / dash và họ không nhận nội dung của ~ / .bashrc hoặc ~ / .profile.

Tôi cho rằng tôi có thể thay đổi tất cả các phím tắt này thành sử dụng / bin / bash thay vì / bin / sh để buộc nó phải nhận các thay đổi .bashrc, nhưng điều đó có vẻ rất khó khăn.

Cho rằng Ubuntu 12.04 (theo mặc định) bí danh / bin / sh thành / bin / dash và vỏ mặc định của tôi là / bin / bash, có một nơi duy nhất mà tôi có thể chọn để sửa đổi PATH và xác định các biến môi trường nếu tôi muốn có mặt trong tất cả các trường hợp sau:

  1. Bất cứ khi nào tôi tạo một vỏ bash không đăng nhập (sử dụng thiết bị đầu cuối trong sự thống nhất)
  2. Bất cứ khi nào tôi tạo shell bash đăng nhập (ví dụ: đăng nhập từ xa qua ssh)
  3. Bất cứ khi nào tôi sử dụng trình khởi chạy ứng dụng Unity (cho rằng trình khởi chạy sử dụng / bin / sh).
  4. Bất cứ khi nào một công việc cron thực thi (được cho là SHELL = / bin / sh in / etc / crontab).

Nếu tôi hiểu chính xác, tôi đoán rằng:

  • (1) / (2) và (3) / (4) khác nhau vì (1) / (2) là bash và (3) / (4) là dấu gạch ngang.
  • (1) và (2) khác nhau vì các tệp bash chọn tải khác nhau tùy thuộc vào việc nó có phải là vỏ đăng nhập hay không.
  • (3) và (4) khác nhau vì (3) sẽ đến vào một lúc nào đó sau khi tôi đăng nhập (và do đó ~ / .profile sẽ có nguồn gốc từ một trong các quy trình mẹ của nó, trong khi (4) sẽ đến một số điểm khi tôi chưa đăng nhập và do đó ~ / .profile sẽ không được đọc.

(Tôi sẽ không ngạc nhiên nếu các yếu tố khác cũng vậy, chẳng hạn như vỏ có tương tác hay không, do đó, có thể có nhiều kết hợp mà tôi thậm chí không lường trước được ... Tôi rất vui khi câu hỏi của mình "được cải thiện " trong trường hợp đó.)

Tôi hy vọng rằng đến một lúc nào đó, ai đó phải thực hiện một số hướng dẫn cho bạn biết cách / nơi sửa đổi các biến môi trường theo cách độc lập với vỏ (hoặc ít nhất là cách tương thích dash / bash) ... Tôi chỉ có thể ' t dường như tìm thấy các thuật ngữ tìm kiếm phù hợp để tìm hướng dẫn như vậy.

Giải pháp hoặc con trỏ đến giải pháp đánh giá rất cao!

Đã cập nhật:

  • Làm rõ: Đây là người dùng Ubuntu mặc định được tạo bởi quá trình cài đặt 12.04, vì vậy không có gì lạ mắt. Nó không có một ~ / .profile (mà các nguồn rõ ràng ~ / .bashrc), và chỉ ~ / bash * tập tin hiện nay là .bashrc, .bash_history, và bash_logout ... vì vậy không không có .bash_profile.
  • Nhấn mạnh vào phạm vi: Tôi không thực sự quan tâm đến bất kỳ shell nào ngoài shell tương tác mặc định (bash) và bất kỳ tập lệnh nào xảy ra để sử dụng / bin / sh (bí danh cho dấu gạch ngang), vì vậy không cần phải phức tạp hóa điều này với bất kỳ điều gì thêm cho tcsh / ksh / zsh / v.v. ủng hộ.

2
Đặt nó trong một tập tin sau đó để cho các tập tin RC khác nguồn nó.
konsolebox

Theo trang dash man tôi có ở đây, nó nên đọc $ HOME / .profile cho các shell đăng nhập.
Etan Reisner

@konsolebox Những tập tin RC nào? AFAICT, dash không có tệp RC. Và như tôi đã nói, dash dường như không chọn nội dung của ~ / .profile.

@EtanReisner Vâng, và đây là điểm của câu hỏi. Khi dấu gạch ngang không chạy như một vỏ đăng nhập (và do đó ~ / .profile không có nguồn gốc), thì sao?

@Mickalot Bạn đang chạy dash tương tác? Nếu không cố gắng thêm tùy chọn -l cho nó.
konsolebox

Câu trả lời:


9

Shell gọi là một chút của một điều phức tạp. Các trang bash và dash man có INVOCATIONcác phần về điều này.

Tóm lại họ nói (có nhiều chi tiết hơn trong trang man, bạn nên đọc nó):

When bash is                   | it reads
-------------------------------|----------
login shell                    | /etc/profile and then the first of ~/.bash_profile, ~/.bash_login or ~/.profile that exists.
                               |
interactive non-login shell    | /etc/bash.bashrc then ~/.bashrc
                               |
non-interactive shell          | The contents of $BASH_ENV (if it exists)
                               |
interactive (as "sh")          | The contents of $ENV (if it exists)

-

When dash is                   | it reads
-------------------------------|---------
login shell                    | /etc/profile then .profile
                               |
interactive shell              | The contents of ENV (it it exists, can be set in .profile as well as in initial environment)

Tôi không biết về các loại đạn pháo khác vì tôi không bao giờ sử dụng chúng. Đặt cược tốt nhất của bạn có thể là đặt một vài biến môi trường để trỏ đến tập lệnh vị trí chung và lấy nguồn theo cách thủ công (khi thích hợp) trong một vài trường hợp không bao gồm.


Đáng buồn thay, mấu chốt của vấn đề này là vấn đề còn thiếu trong bảng gạch ngang của bạn. Khi máy tính để bàn Unity gọi bất kỳ tập lệnh nào bắt đầu bằng #! / Bin / sh, nó sẽ khởi chạy (cái mà tôi giả sử là) một vỏ dash không đăng nhập, không tương tác. Vì vậy, câu hỏi là: làm thế nào để tôi tạo ra các biến môi trường giống nhau có sẵn đó có mặt ở mọi nơi khác trong ma trận?

Đúng. Tôi tưởng tượng đó là lý do tại sao bash thêm BASH_ENV cho vị trí đó. Do dấu gạch ngang dường như không có bất cứ thứ gì hoạt động trong khe đó, tôi không chắc bạn có thể giải quyết vấn đề đó mà không ảnh hưởng đến sự thay đổi trong môi trường của ứng dụng khởi chạy dấu gạch ngang (như dấu gạch ngang đó kế thừa nó). Điều này sẽ yêu cầu các biến môi trường được đặt trong môi trường X của bạn, đó là nơi nhận xét .xsession (RC) từ @Mickalot phát huy tác dụng. Điều này vẫn để lại, như ông chỉ ra, mục bốn còn lại (nhưng tôi tin rằng điều đó thực sự có phần có chủ ý).
Etan Reisner

Vì tôi đang dùng Ubuntu 12.04 LTS, cron thực sự là pixie-cron, vì vậy tôi có thể xác định các biến env trong tệp crontab của mình ... Tôi đoán SHELL = / bin / bash và BASH_ENV = ~ / .bashrc nên làm gì?

3

Vì vậy, có một số cách để tiếp cận điều này. Nhiều người cũng sẽ:

a. Có một tệp có những thứ chung cho tất cả các vỏ kiểu sh của bạn, giả sử .shcommonvà trong mỗi .profile .bashrc .kshrcet cetra, chỉ cần nguồn này với. .shcommon

b. Đặt mọi thứ vào .profilevà lấy nguồn này từ các tệp khác.

Những thứ cần thiết cho các shell cụ thể hoặc cho các shell tương tác và không tương tác sau đó có thể đi vào tệp thích hợp trước khi tìm nguồn cung ứng .shcommon

Cá nhân, tôi không thích quản lý nhiều tập tin. Vì vậy, tôi sử dụng cách tiếp cận sau:

Đầu tiên, mọi thứ tôi cần .profile đều có vì tôi có một số thứ cụ thể bash và ksh, tôi xác định tên shell hiện tại bằng cách sử dụng như sau:

# get name of current shell
# strip leading - from login shell
export SHELLNAME="${0#-}"

và sau đó có các lệnh cho các shell cụ thể trong một số thứ như sau (một số sẽ thích một câu lệnh tình huống).

if [ "$SHELLNAME" = 'bash' ]
then
    shopt -s checkwinsize

elif [ "$SHELLNAME" = 'ksh' ]
then
    stty erase ^?
fi

Nếu tôi có các lệnh chỉ nên chạy trong shell tương tác, tôi sử dụng như sau:

# check for interactive flag i in shell options $-
# in bash and ksh you could use the following, but breaks in dash
# if [[ $- == *i* ]]
if [ "$(echo $- | grep i)" != "" ]
then
  fortune
fi

Những thứ phổ biến trong tất cả các vỏ kiểu sh, ví dụ, PATHchỉ có thể đi lên trên cùng.

Sau đó, tôi sử dụng symlink để tải cùng một tệp này trong tất cả các shell kiểu sh:

ln -s .profile .bashrc
ln -s .profile .kshrc

Một vài lưu ý phụ, nếu bạn có a .bash_profile, thì bash sẽ tải cái này thay vì .profilenhưng dash và ksh vẫn sẽ tải .profile Đây có thể là một phần của vấn đề của bạn.

Ngoài ra, bạn có thể muốn xem xét sử dụng #!/bin/bashtrong tập lệnh của mình thay vì #!/bin/dashtrừ khi bạn thực sự muốn tập lệnh tương thích POSIX. bash có rất nhiều tính năng bổ sung rất hay và dấu gạch ngang hoặc bash được gọi vì sh sẽ vô hiệu hóa nhiều tính năng này.

Ngoài ra, trang bash man thực hiện tốt công việc giải thích khi .profileso với .bashrcđược tải. Quy tắc tương tự áp dụng cho ksh. tải dash .profilekhi đăng nhập và cho phép bạn tải một tệp khi khởi động shell tương tác được chỉ định bằng cách sử dụng ENVbiến môi trường trong .profile(cũng kiểm tra trang dash man và tìm kiếm .profile).


Bạn có thể không chỉ kiểm tra $ 0 cho tên shell? Có vỏ / trường hợp không hoạt động?
Etan Reisner

Tương tự, việc kiểm tra i bằng $ - không đủ cho thử nghiệm shell tương tác? (Nó sẽ kích hoạt trên vỏ tương tác mà không có một tty tôi cấp nhưng có thể có hoặc không có thể là một tác dụng phụ không mong muốn.)
Etan Reisner

@Etan: Hrm, tôi biết rằng lần đầu tiên tôi đã thử $0và gặp vấn đề ... Tôi dường như không thể nhớ chính xác những gì họ đã mặc dù. Đăng nhập trực tiếp vào giao diện điều khiển không hiển thị $0như -bashthay vì bashnhưng điều đó có thể được khắc phục.

@Etan: Vâng, kiểm tra cho tôi $-cũng sẽ làm việc. Tôi sẽ phải suy nghĩ khi nào bạn sẽ có một vỏ tương tác mà không có tty? Vì lý do nào đó, giải pháp của bạn có "cảm giác" tốt hơn với nó vì một số lý do, tôi có thể thay đổi điều đó.

Chữ -in -bashcó nghĩa là "vỏ đăng nhập" nhưng có, bạn sẽ cần tính đến điều đó ở những nơi bạn kiểm tra giá trị hoặc muốn hiển thị nó cho ai đó.
Etan Reisner

0

Vì các trường hợp (1) và (2) được giải quyết bằng cách tìm nguồn cung cấp các biến môi trường của tôi trong .bashrc và .profile, nên câu hỏi thực sự là "tên của tệp nơi tôi cung cấp các biến tương tự cho (3) và (4).

Dường như có câu trả lời cho phần (3) của câu hỏi (làm cách nào để biến biến môi trường được nhập trong máy tính để bàn Unity) trên Askubfox . Đề xuất là tạo một tệp ~ / .xsessionrc sẽ có nguồn gốc bởi / etc / X11 / Xsession. (Tôi đã thử điều này và có vẻ như nó hoạt động ... yay!)

Tôi vẫn còn bối rối vì phải làm gì (4). Chắc chắn, nếu tôi tạo một cron job (hoặc daemon), tôi có thể thay thế '/ bin / foo' bằng một cái gì đó như 'bash -i -c / bin / foo' để buộc nó sử dụng bash để tải đúng biến môi trường, nhưng điều này cũng có nghĩa là tôi sẽ phải sửa đổi bất kỳ công cụ của bên thứ ba nào có thể cài đặt các tác vụ daemon hoặc công việc định kỳ thay cho tôi. Yuk.

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.