Không thể mã nguồn thành công .bashrc từ tập lệnh shell


51

Thông thường chúng ta có thể nguồn ~/.bashrctập tin bằng cách sử dụng lệnh này

source ~/.bashrc

nhưng nếu tôi viết nó trong một kịch bản shell và thực thi nó, không có gì xảy ra. Tại sao?
Có cách nào để làm điều này?

Kịch bản của tôi:

#!/bin/bash
chmod a+x ~/.bashrc
source ~/.bashrc

Cũng đã thử .(chấm) thay vì source. Cùng một kết quả.

Câu trả lời:


26

Một kịch bản shell được chạy trong thể hiện shell của chính nó. Tất cả các cài đặt biến, định nghĩa hàm và như vậy chỉ ảnh hưởng đến trường hợp này (và có thể là con của nó) nhưng không phải là vỏ gọi để chúng biến mất sau khi tập lệnh kết thúc.

Ngược lại, sourcelệnh không khởi động một thể hiện shell mới mà sử dụng shell hiện tại để các thay đổi vẫn còn.

Nếu bạn muốn một phím tắt để đọc .bashrc, hãy sử dụng hàm shell hoặc bí danh thay vì tập lệnh shell, như

alias brc='source ~/.bashrc'

Cảm ơn vì đã phản hồi sớm. Giải pháp của bạn có thể hoạt động nhưng tôi phải chỉnh sửa tệp bashrc theo cách thủ công để lưu dòng 'aliac brc = ....'. Tôi đang cố gắng phát triển một gui để thay đổi biến môi trường. Vì vậy, tôi không thể chỉnh sửa tệp bashrc của máy tính khác bằng tay.
shantanu

1
Bạn phải chạy source ~/.bashrctrong vỏ mà bạn muốn thay đổi môi trường. Bạn không thể thay đổi nó từ một quá trình khác. Có thể (trên toàn cầu) thêm bí danh này có thể là một phần của quy trình cài đặt GUI của bạn.
Florian Diesch

1
Vì vậy, tôi có đặt lệnh bí danh của bạn sớm hơn trong tập lệnh và sau đó gọi brc khi tôi muốn nguồn .bashrc của tôi hoặc tôi cần đặt lệnh bí danh đó trong một tệp ở đâu đó?
dùng137717

Điều cuối cùng tôi làm là một phần mở rộng của câu trả lời của Florian Diesch. Bạn chỉ có thể sử dụng một bí danh nhiều dòng: alias brc = 'chmod a + x ~ / .bashrc; nguồn ~ / .bashrc 'Tôi vẫn còn khá mới, vì vậy tôi không chắc liệu đây có được coi là' thực hành kém 'hay không. Nó làm việc mặc dù.
A_user_appears

13

Bạn .bashrcthường bắt đầu:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Vì tập lệnh của bạn không có bộ PS1 (vì nó không tương tác), nên nó không đặt lại đường dẫn vì nó thoát sớm. Để chứng minh, sửa đổi tập lệnh của bạn:

    #!/bin/bash
    chmod a+x ~/.bashrc
    PS1='$ '
    source ~/.bashrc

điều này bây giờ sẽ cho phép các tập lệnh của bạn hoạt động với cái mới .bashrc. Lưu ý: một khi tập lệnh của bạn thoát, env sẽ được đặt thành trước khi bắt đầu tập lệnh. Những thay đổi sẽ được phản ánh trong lần tiếp theo thiết bị đầu cuối được bắt đầu.


Ít nhất là từ 16.04 và có lẽ trước đó, Ubuntu mặc định .bashrcsử dụng một cách đáng tin cậy hơn để kiểm tra xem trình bao có tương tác hay không. /etc/bash.bashrcvẫn có bài kiểm tra PS1.
Zanna

12

Thử:

exec bash

Điều này sẽ tải lại ~ / .bashrc, ~ / .bash_aliases, v.v.


9
Điều này thay thế quá trình bash hiện tại bằng một quy trình mới. Nó không ngắn hơn hoặc dễ dàng hơn nhiều so với việc sử dụng sourcenhưng phá hủy mọi biến số và do đó người dùng đã đặt thủ công - có thể hoặc không thể những gì bạn muốn.
Florian Diesch

Xin chờ, trong ngữ cảnh của tập lệnh Shell với các lệnh khác sau khi tìm nguồn bashrc, bạn có đặt các lệnh cần trạng thái bash mới sau đó không exec bash, theo cách tôi hiểu lệnh sau đó vẫn sẽ ở cùng cài đặt bash như trước?
tatsu

11

Tôi muốn bổ sung cho câu trả lời của ravi :

Hành vi này là dành riêng cho Ubuntu (và có lẽ hầu hết các bản phát hành có nguồn gốc), vì ~/.bashrctệp mặc định của bạn bắt đầu bằng một mạch ngắn, ví dụ Ubuntu 18.04, ví dụ:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

Điều đó sẽ dừng việc đánh giá tệp nếu nó đang chạy trong trình bao không tương tác, đó là trường hợp tập lệnh của bạn vì tất cả các tập lệnh được chạy trong trình bao không tương tác và sau đó mọi tệp bạn sourcesẽ thừa hưởng thuộc tính này.

eval gian lận

Tôi đã phát hiện ra một bản hack xấu xí để khắc phục Ubuntu, sử dụng evalthay vì source:

eval "$(cat ~/.bashrc | tail -n +10)"

Nó chỉ đơn giản bỏ qua một vài dòng đầu tiên và đánh giá phần còn lại ~/.bashrcđể phần còn lại được đánh giá và sửa đổi thực thi hiện tại.

Xin lưu ý rằng đây là một con số kỳ diệu và có thể không hoạt động trên các phiên bản Ubuntu; nhưng có thể là một giải pháp tốt nếu bạn đang tạo các tập lệnh cho các hệ thống ít được biết đến.

Một giải pháp fancier có thể liên quan đến việc sử dụng regex để nhắm mục tiêu các bit cụ thể dừng đánh giá.

Shebang thay thế

Một cách khác có thể hoạt động tốt hơn trong một số trường hợp là buộc tập lệnh chạy trong trình bao tương tác bằng cách thêm cờ trong shebang :

#!/bin/bash -i

Hãy nhận biết một số điều:


2

Không có phương pháp nào khác làm việc cho tôi [ source /path/to/filevs . ./path/to/file, bí danh, v.v ...], cho đến khi, nhờ vào hướng dẫn này, tôi thấy rằng bằng cách sử dụng:

#!/usr/bin/env bash shebang

thay vì đơn giản hơn, hãy #!/usr/bin/envcho phép các đối số chuyển đến trình thông dịch, mà tôi nghĩ là chìa khóa ở đây - xem tài liệu này để biết thêm thông tin.

Trong mọi trường hợp, nếu các lệnh nguồn dưới mọi hình thức không hoạt động với bạn, hãy thử kiểm tra shebang của bạn, đó có thể là vấn đề :)

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.