Làm cách nào để xuất VAR từ vỏ con sang vỏ cha?


10

Tôi có một kịch bản shell Korn

#!/bin/ksh
# set the right ENV
case $INPUT in
abc)
  export BIN=${ABC_BIN}
  ;;
  def)
  export BIN=${DEF_BIN}
  ;;
  *)
  export BIN=${BASE_BIN}
  ;;
esac
# exit 0 <- bad idea for sourcing the file

bây giờ các VAR này chỉ được xuất trong một khung con, nhưng tôi cũng muốn chúng được đặt trong vỏ cha mẹ của mình, vì vậy khi tôi ở dấu nhắc thì các vars đó vẫn được đặt chính xác.

Tôi biết về

. .myscript.sh

Nhưng có cách nào để làm điều đó mà không cần 'tìm nguồn cung ứng' không? như người dùng của tôi thường quên 'nguồn'.


EDIT1: xóa phần "exit 0" - đây chỉ là tôi gõ mà không suy nghĩ trước

EDIT2: để thêm chi tiết về lý do tại sao tôi cần điều này: các nhà phát triển của tôi viết mã cho (vì đơn giản) 2 ứng dụng: ABC & DEF. mọi ứng dụng được chạy trong sản xuất bởi những người dùng riêng biệt usrabc và usrdef, do đó đã thiết lập $ BIN, $ CFG, $ ORA_HOME, bất cứ điều gì - cụ thể cho ứng dụng của họ.

vì thế

  • $ BIN = / opt / abc / bin # $ ABC_BIN của ABC trong tập lệnh trên
  • $ BIN = / opt / def / bin # $ DEF_BIN của DEF

Vân vân.

bây giờ, trên các nhà phát triển hộp dev có thể phát triển cả ABC và DEF cùng một lúc trong tài khoản người dùng 'justin_case' của riêng họ và tôi tạo cho họ nguồn tệp (ở trên) để họ có thể chuyển đổi cài đặt var ENV của họ qua lại. ($ BIN nên trỏ đến $ ABC_BIN cùng một lúc và sau đó tôi cần chuyển sang $ BIN = $ DEF_BIN)

Bây giờ, tập lệnh cũng sẽ tạo các hộp cát mới để phát triển song song cùng một ứng dụng, v.v ... điều này khiến tôi phải thực hiện nó một cách tương tác, yêu cầu tên hộp cát, v.v.

  • / nhà / justin_case / sandbox_abc_beta2
  • / nhà / justin_case / sandbox_abc_r1
  • / nhà / justin_case / sandbox_def_r1

tùy chọn khác tôi đã xem xét là viết bí danh và thêm chúng vào hồ sơ của mọi người dùng

  • bí danh 'setup_env =. .myscript.sh '

và chạy nó với

  • setup_env tham số1 ... tham sốX

điều này có ý nghĩa hơn với tôi bây giờ


Có - bạn có thể thực hiện việc này với bí danh hoặc hàm (tôi thích các hàm hơn) trong đó bạn có hàm prod () {export VAR = snoopy; }; và hàm dev () {export VAR = woodstock; };
chris

Câu trả lời:


11

Tôi nghĩ đó là một vấn đề "không thể làm được" ...

Đầu tiên - bạn sẽ không muốn lấy tập lệnh đó vì thoát 0 ở cuối.

Thứ hai, không có quá trình con unix có thể trực tiếp thay đổi môi trường của cha mẹ. Nếu không thì tất cả những thứ điên rồ sẽ có thể.

Bạn có thể thêm một cái gì đó vào môi trường của họ với hồ sơ mặc định hoặc các tệp bashrc, hoặc bạn có thể viết một trình bao bọc cho bất kỳ chương trình nào mà họ đang cố gắng chạy không?

Cho phép tôi giải thích khái niệm "trình bao bọc".

Giả sử bạn muốn chạy chương trình rình mò chương trình với SẢN PHẨM hoặc DEV trong biến môi trường "TÙY CHỌN" tùy thuộc vào việc bạn muốn sản xuất hay phát triển. NẾU nó không được thiết lập, giả sử snoopy làm một cái gì đó giống như xóa sạch cơ sở dữ liệu để sản xuất và phát triển ...

đổi tên "snoopy" thành snoopy.bin (hoặc .snoopy.bin)

sau đó đặt một tập lệnh vào cùng vị trí có tên "snoopy" có chứa đoạn này:

#!/bin/sh

export OPTIONS

case "$OPTIONS" 
in
  PROD) ;;
  DEV) ;;
  *) OPTIONS=DEV ;;
esac

#the binary is actually named snoopy.bin 

exec "$0.bin" "$@"

Nếu bạn không muốn làm hỏng tập tin thực tế, hãy đặt tập lệnh này ở đâu đó trong hệ thống tập tin đi trước chương trình rình mò thực tế trong PATH của người dùng và có đường dẫn đầy đủ đến tệp nhị phân trong câu lệnh exec của tập lệnh ...


5

Câu trả lời là tìm nguồn cung ứng. Tìm nguồn cung cấp cho phép bạn bao gồm các biến trong một tập lệnh trong trình bao hiện tại , nhưng không bao giờ là cha mẹ của điều đó. Đó là sự thật, bạn phải cẩn thận không sử dụng bất kỳ lệnh thoát hoặc tương tự, bởi vì điều đó sẽ đóng vỏ hiện tại của bạn.

Bạn có thể nguồn tập lệnh bằng cách sử dụng ".", Tức là

. ./myscript.ksh



3

Có lẽ nếu bạn cố gắng ...

#!/bin/bash

mknod fifo p

(
       echo 'value' > fifo &
)

VARIABLE=`cat fifo`
rm fifo

Nó không chính xác xuất khẩu, nhưng nó có thể cung cấp giao tiếp cơ bản với quy trình cha.


1

OK, đừng cười nữa. Giải pháp rất nhanh và rất bẩn là thêm

echo "Please copy and paste this command:"
echo ""
echo "export BIN=\"$BIN\""

đến kịch bản của bạn.

Một cách tiếp cận khác . Chỉ execlà cấp dưới $ SHELL trong tập lệnh của bạn, có thể bằng một dấu nhắc khác (thay đổi $ PS1 để thông báo cho người dùng trong môi trường nào họ đang làm việc để giảm nhầm lẫn).

Một cách tiếp cận khác (yêu thích của tôi). Người dùng quên nguồn kịch bản của bạn, tại sao vậy? Tìm nguồn cung ứng chính xác là cách tiêu chuẩn để đi. Có lẽ một cách tốt để nhắc nhở họ là xóa dòng đầu tiên ( #!/bin/sh) và sau đó chmod a-xnó. Nó có thể vẫn có nguồn gốc sau đó, nhưng rõ ràng nó không thể bị thực thi sai.

Rant : Tất cả trong tất cả, tôi cảm thấy bạn đã có một ý tưởng kỳ lạ ngay từ đầu. Có lẽ không có gì lạ ... Tôi có thể nói hơi phi Unix theo phong cách. Tôi chưa bao giờ cần xuất khẩu môi trường cho cha mẹ trong đời. Tôi đã thấy một lần một tình huống tương tự - đăng nhập .profile hỏi về ba môi trường khác nhau để thiết lập cho một tài khoản sấm. Ý tưởng tồi, cuối cùng hóa ra người dùng thích chuyển sang sudo (họ sudo'd đến ba tài khoản oraxxx khác nhau). Bạn đang cố gắng đạt được điều gì, nếu tôi có thể hỏi?

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.