2012-03-09 35 views
121

Khi tôi sử dụng lệnh exit trong tập lệnh shell, tập lệnh sẽ chấm dứt thiết bị đầu cuối (lời nhắc). Có cách nào để chấm dứt một kịch bản và sau đó ở trong nhà ga?Bất kỳ cách nào để thoát tập lệnh bash, nhưng không thoát terminal

Tập lệnh của tôi run.sh được dự kiến ​​sẽ thực thi bằng cách trực tiếp lấy nguồn gốc hoặc được lấy từ tập lệnh khác.

EDIT: Để cụ thể hơn, có hai kịch bản run2.sh như

... 
. run.sh 
echo "place A" 
... 

run.sh như

... 
exit 
... 

khi tôi chạy nó bằng cách . run2.sh, và nếu nó nhấn exit codeline trong run.sh , Tôi muốn nó dừng lại ở nhà ga và ở đó. Nhưng sử dụng exit, toàn bộ thiết bị đầu cuối bị đóng.

PS: Tôi đã cố gắng sử dụng return, nhưng echo codeline sẽ vẫn được thực hiện ....

+3

Tôi thực sự, thực sự, thực sự phải hỏi: tại sao bạn sử dụng lối ra trong tập lệnh có nguồn gốc? –

+3

lệnh thoát không nên chấm dứt phiên đăng nhập/đăng nhập của bạn. nếu bạn sử dụng 'exit 0' để chấm dứt tập lệnh sau khi thành công, khi bạn chạy tập lệnh cũ của bạn:'./test.sh' bạn sẽ thấy đầu ra nhưng bảng điều khiển của bạn sẽ vẫn mở. –

+0

Bạn có thể sử dụng lệnh 'shell', mở ra trên thực tế một thiết bị đầu cuối vỏ. Tuy nhiên, kinh nghiệm của riêng tôi là điều này không xảy ra với 'thoát'. Thoát bình thường sẽ trả về điều khiển cho tập lệnh gốc. –

Trả lời

173

"Vấn đề" thực sự là bạn đang tìm nguồn cung ứng và không thực thi tập lệnh. Khi bạn nguồn một tập tin, nội dung của nó sẽ được thực hiện trong trình bao hiện tại, thay vì sinh ra một vỏ bọc con. Vì vậy, tất cả mọi thứ, bao gồm cả thoát, sẽ ảnh hưởng đến vỏ hiện tại.

Thay vì sử dụng exit, bạn sẽ muốn sử dụng return.

+1

Đây là một giải thích khác mà tôi thấy hữu ích: http://askubuntu.com/a/53179/148337 – 3cheesewheel

+0

Mặc dù đúng, đây không phải là một câu trả lời tuyệt vời. Nó bỏ qua rằng kịch bản lệnh gọi có thể khai báo các biến hoặc các hàm gọi là kịch bản lệnh cần truy cập. Tốt hơn để giải thích làm thế nào để thiết lập một mã trả về và sau đó xử lý nó trong 'runs.sh' @ruakh có câu trả lời tốt hơn cho câu hỏi này. – MikeSchinkel

+3

Nếu chức năng là cuộc gọi lồng nhau thì sao? tức là một cuộc gọi b, b gọi c, c muốn thoát ngay lập tức a và b. – Michael

-2

1) exit 0 sẽ đi ra của kịch bản nếu nó là thành công.

2) thoát 1 sẽ thoát ra khỏi tập lệnh nếu đó là lỗi.

Bạn có thể thử hai cách trên dựa trên yêu cầu của ur.

29

Có; bạn có thể sử dụng return thay vì exit. Mục đích chính của nó là để trở về từ một hàm shell, nhưng nếu bạn sử dụng nó trong một script source -d, nó trả về từ kịch bản đó.

Như §4.1 "Bourne Shell Builtins" of the Bash Reference Manual đặt nó:

 return [n] 

Nguyên nhân chức năng một vỏ để thoát với giá trị trả về n. Nếu n không được cung cấp, giá trị trả lại là trạng thái thoát của lệnh cuối cùng được thực thi trong hàm. này cũng có thể được sử dụng để chấm dứt thực hiện một kịch bản được thực thi với . (hoặc source) được xây dựng trong, trở về một trong hai n hoặc trạng thái thoát của lệnh cuối cùng được thực hiện trong kịch bản là trạng thái thoát của kịch bản . Bất kỳ lệnh nào liên quan đến bẫy RETURN được thực thi trước khi thực thi tiếp tục lại sau hàm hoặc tập lệnh. Trạng thái trả về khác 0 nếu return được sử dụng bên ngoài chức năng và không trong khi thực thi tập lệnh theo số . hoặc source.

2

Điều này giống như bạn đặt một hàm chạy bên trong tập lệnh run2.sh. Bạn sử dụng mã thoát trong khi chạy trong khi nguồn tập tin run2.sh của bạn trong tash bash. Nếu cung cấp cho chức năng chạy sức mạnh của nó để thoát khỏi kịch bản của bạn và cung cấp cho run2.sh sức mạnh của nó để thoát khỏi terminator. Sau đó, cuz chức năng chạy có quyền lực để thoát khỏi teminator của bạn.

#! /bin/sh 
    # use . run2.sh 

    run() 
    { 
     echo "this is run" 
     #return 0 
     exit 0 
    } 

    echo "this is begin" 
    run 
    echo "this is end" 

Dù sao, tôi đồng ý với Kaz đó là vấn đề thiết kế.

0

nếu mô phỏng thiết bị của bạn không có -hold bạn có thể khử trùng một kịch bản nguồn và giữ thiết bị đầu cuối với:

#!/bin/sh 
sed "s/exit/return/g" script >/tmp/script 
. /tmp/script 
read 

nếu không bạn có thể sử dụng $TERM -hold -e script

2

Tôi nghĩ rằng điều này xảy ra bởi vì bạn đang chạy ở chế độ nguồn với dấu chấm

. myscript.sh 

Bạn nên chạy nó trong một vỏ:

/full/path/to/script/myscript.sh 

'nguồn' http://ss64.com/bash/source.html

+0

Bạn không cần đường dẫn đầy đủ đến tập lệnh nếu'. myscript.sh' hoạt động. Tối đa, bạn có thể cần './Myscript.sh'. –

0

Ngoài ra hãy chắc chắn để trở lại với giá trị lợi nhuận kỳ vọng. Khác nếu bạn sử dụng lối ra khi bạn sẽ gặp phải một lối ra nó sẽ thoát khỏi vỏ cơ sở của bạn kể từ khi nguồn không tạo ra một quá trình (ví dụ).

9

Thay vì chạy mã sử dụng . run2.sh bạn có thể chạy các kịch bản sử dụng sh run2.sh hoặc bash run2.sh
Một ví dụ mới sẽ được mở ra để chạy các kịch bản sau đó nó sẽ đóng cửa vào cuối của kịch bản rời khỏi vỏ khác mở ra. `

+0

Nếu có, thì tại sao tham số thứ hai là "sh". " run2.sh'? – H0WARD

+0

@ H0WARD Bạn nói đúng Tôi đã quên xóa các dấu chấm. Tôi đã chỉnh sửa câu trả lời ngay bây giờ. –

+0

OP nêu rõ nguồn là yêu cầu. –

0

Chính xác là tập lệnh được thực thi so với mã được thực thi sử dụng return và giữ exit để giữ cùng một phiên mở, như những người khác đã lưu ý.

Đây là mẹo liên quan, nếu bạn muốn một tập lệnh nên giữ phiên mở, bất kể nó có nguồn gốc hay không.

Ví dụ sau có thể chạy trực tiếp như foo.sh hoặc có nguồn gốc như . foo.sh/source foo.sh. Dù bằng cách nào nó sẽ giữ cho phiên mở sau khi "thoát". Chuỗi [email protected] được truyền để hàm có quyền truy cập vào đối số của tập lệnh bên ngoài.

#!/bin/sh 
foo(){ 
    read -p "Would you like to XYZ? (Y/N): " response; 
    [ $response != 'y' ] && return 1; 
    echo "XYZ complete (args [email protected])."; 
    return 0; 
    echo "This line will never execute."; 
} 
foo "[email protected]"; 

ga kết quả:

$ foo.sh
$ Bạn có muốn để XYZ? (Y/N): n
$. foo.sh
$ Bạn có muốn XYZ không?(Y/N): n
$ |
(cửa sổ terminal vẫn mở và chấp nhận đầu vào bổ sung)

này có thể hữu ích để nhanh chóng kiểm tra những thay đổi kịch bản trong một thiết bị đầu cuối đơn trong khi vẫn giữ một bó mã phế liệu bên dưới chính exit/return khi bạn làm việc. Nó cũng có thể làm cho mã di động hơn theo nghĩa (nếu bạn có tấn tập lệnh có thể hoặc không thể gọi theo nhiều cách khác nhau), mặc dù ít phức tạp hơn khi chỉ sử dụng returnexit nếu thích hợp.

Các vấn đề liên quan