Tải lại .profile trong tập lệnh bash shell (trong unix)?


130

Tôi chưa quen với bash shell scripting, và đã gặp một thử thách. Tôi biết tôi có thể tải lại tệp ".profile" của mình chỉ bằng cách thực hiện:

. .profile

nhưng tôi đang cố gắng thực hiện tương tự trong một tập lệnh bash tôi đang viết và nó chỉ không hoạt động. Có ý kiến ​​gì không? Bất cứ điều gì khác tôi có thể cung cấp để làm rõ?

Cảm ơn


Như Ignacio chỉ ra bên dưới, tập lệnh của bạn đang chạy trong một khung con. Subshell không thể sửa đổi shell chính (tiến trình con không thể sửa đổi cha mẹ của nó). Vì vậy, bạn cần "nguồn" tập lệnh bằng cách sử dụng "." lệnh (cũng có thể được đánh vần là "nguồn"). Vì vậy, nếu tập lệnh của bạn muốn, nói, sửa đổi các biến môi trường, bạn cần phải làm một cái gì đó như "myscript nguồn" hoặc ". Myscript" (cả hai đều có nghĩa giống nhau). Điều này sẽ sửa đổi môi trường vỏ chính của bạn. (Mà tôi nghĩ là những gì bạn đang cố gắng làm, hãy cho tôi biết nếu điều này là sai.)
bstpierre

1
Tôi đã nhận được câu trả lời từ câu hỏi của bạn :)
Kolob Canyon

Câu trả lời:


195

Hãy thử điều này để tải lại shell hiện tại của bạn:

source ~/.profile

1
Bạn có một giải pháp thay thế? Bởi vì sử dụng sourcelệnh sẽ chạy tệp dưới dạng tập lệnh ... Trong trường hợp xấu nhất, nếu ai đó sử dụng phép gán biến như MyVar="$foo$MyVar"trong bash_profile của họ, thì source ~/.profilesẽ đưa ra kết quả cuối cùng MyVar="$foo$MyVar$MyVar", do đó $MyVarsẽ có giá trị sai sau đó. (Bất kể thực hành xấu, chỉ cần yêu cầu một giải pháp thay thế)
Jeffrey Mvutu Mabilama


5

Một số vấn đề phát sinh khi cố gắng tải lại tập tin / nguồn ~ / .profile. [Điều này đề cập đến Ubuntu linux - trong một số trường hợp, chi tiết của các lệnh sẽ khác nhau]

  1. Bạn đang chạy trực tiếp trong thiết bị đầu cuối hoặc trong một kịch bản?
  2. Làm thế nào để bạn chạy này trong một kịch bản?

Quảng cáo. 1)

Chạy nó trực tiếp trong thiết bị đầu cuối có nghĩa là sẽ không có subshell được tạo. Vì vậy, bạn có thể sử dụng một trong hai lệnh:

source ~/.bash_profile

hoặc là

. ~/.bash_profile

Trong cả hai trường hợp, điều này sẽ cập nhật môi trường với nội dung của tệp .profile.

Quảng cáo 2) Bạn có thể bắt đầu bất kỳ tập lệnh bash nào bằng cách gọi

sh myscript.sh 

hoặc là

. myscript.sh

Trong trường hợp đầu tiên, điều này sẽ tạo ra một lớp con sẽ không ảnh hưởng đến các biến môi trường của hệ thống của bạn và chúng sẽ chỉ hiển thị với quy trình của lớp con. Sau khi hoàn thành lệnh subshell, không xuất khẩu, vv sẽ không được áp dụng. ĐÂY LÀ MỘT CÂU HỎI THƯỜNG GẶP VÀ gây ra rất nhiều nhà phát triển để mất rất nhiều thời gian.

Để các thay đổi của bạn được áp dụng trong tập lệnh của bạn có hiệu lực đối với môi trường toàn cầu, tập lệnh phải được chạy với

.myscript.sh

chỉ huy.

Để đảm bảo rằng tập lệnh của bạn không bị chạy trong một khung con, bạn có thể sử dụng chức năng này. (Một ví dụ nữa là dành cho Ubuntu shell)

#/bin/bash

preventSubshell(){
  if [[ $_ != $0 ]]
  then
    echo "Script is being sourced"
  else
    echo "Script is a subshell - please run the script by invoking . script.sh command";
    exit 1;
  fi
}

Tôi hy vọng điều này sẽ xóa một số hiểu lầm phổ biến! : D Chúc may mắn!


4

Kịch bản bash chạy trong một khung con riêng biệt. Để thực hiện công việc này, bạn cũng cần phải có nguồn kịch bản khác.


Tôi không chắc chắn (vẫn còn mới đối với tất cả những điều này) ý nghĩa chính xác của bạn là "nguồn" -ing script khác. Xin vui lòng mở rộng một chút về điều đó. Tuy nhiên tôi đã thử: $. ~ / .profile $. / etc / hồ sơ không thành công. Cảm ơn bạn rất nhiều.
Amir Rustamzadeh

1
@amirrustan: Tập lệnh của bạn sẽ cần lấy nguồn của .profiletập tin của bạn như thế này: . $HOME/.profilevà bạn cũng sẽ cần phải bắt đầu tập lệnh của mình bằng cách tìm nguồn cung ứng. Một cái gì đó như. /path/to/yourscript
Tạm dừng cho đến khi thông báo thêm.

1
@amirrustam vui lòng đọc superuser.com/questions/176783/ từ
lesmana

1

Thử:

#!/bin/bash
# .... some previous code ...
# help set exec | less
set -- 1 2 3 4 5  # fake command line arguments
exec bash --login -c '
echo $0
echo $@
echo my script continues here
' arg0 "$@"
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.