Sự khác biệt giữa việc sử dụng; và thực hiện một kịch bản


7

Tôi đang sử dụng bashlàm vỏ chính của mình, nhưng đó là một câu hỏi mở và trả lời cho các vỏ khác hơn bashlà rất đáng hoan nghênh.

Nếu tôi đang gõ tương tác

#original line 
#wget http://something.com && unzip something && mv -f something /home/poney/ 
#new line
wget http://something.com ; unzip something ; mv -f something /home/poney/

Liệu nó có làm cho bất kỳ sự khác biệt về thời hạn của cọc thực hiện, thứ tự, bộ nhớ, giải thích, quyền so với một tập lệnh có chứa các dòng đó:

#!/bin/bash
wget http://something.com
unzip something 
mv -f something /home/poney/

Tái bút

ngoại trừ thực tế là việc thực thi một tập lệnh ngắn hơn so với việc gõ 3 lệnh liên tiếp.


1
Tôi không thực sự thuyết phục về sự trùng lặp bởi vì tôi cũng đang hỏi về kịch bản thuần túy, theo ý kiến ​​của tôi khác với vỏ tương tác.
Kiwy


@Kiwy Nhưng bạn đã thay đổi tiêu đề hoàn toàn. Bây giờ thì rõ ràng hơn nhiều.
Bernhard

Câu trả lời:


17

Vâng, có một sự khác biệt lớn. &&ngắn mạch , do đó lệnh tiếp theo sẽ chỉ được thực hiện nếu lệnh trước đó được trả về với mã thoát là 0.

Trích dẫn từ hướng dẫn :

biểu && thức1 biểu thức2

True if both expression1 and expression2 are true.

Mặt khác, một tập lệnh chứa

expression1
expression2

sẽ thực hiện biểu thức thứ hai ngay cả khi lần đầu tiên thất bại. (Trừ khi bạn chỉ định tập lệnh thoát khỏi lỗi bằng cách nói set -e.)


EDIT: Về nhận xét của bạn cho dù:

command1; command2

giống như:

command1
command2

Câu trả lời thường là . Bash phân tích toàn bộ khối lệnh trước khi đánh giá bất kỳ khối nào. A; không làm cho lệnh trước được đánh giá. Nếu lệnh trước đó có ảnh hưởng đến cách lệnh tiếp theo sẽ được phân tích cú pháp, thì bạn sẽ nhận thấy sự khác biệt.

Hãy xem xét một tệp có chứa bí danh, hãy gọi nó alias, với một mục:

alias f="echo foo"

Bây giờ hãy xem xét một tập lệnh chứa:

shopt -s expand_aliases
source ./alias
f

và một cái khác có chứa:

shopt -s expand_aliases; source ./alias; f

sau đó bạn có thể nghĩ rằng cả hai sẽ tạo ra cùng một đầu ra.

Câu trả lời là không. Người đầu tiên sẽ sản xuất foonhưng người thứ hai sẽ báo cáo:

... f: command not found

Để làm rõ hơn, nó không expand_aliasesgây ra vấn đề. Vấn đề là do một tuyên bố như:

alias f="echo foo"; f

sẽ được phân tích cú pháp trong một lần. Shell không thực sự biết nó flà gì , điều này làm cho trình phân tích cú pháp bị sặc.


Được rồi, qe bỏng của tôi nên có vớicommand ; command2; command3
Kiwy

@Kiwy Ý bạn là ;thay vì &&?
devnull

Vì vậy, thực sự bối cảnh thực hiện làm cho việc thực thi một tập lệnh và một tập lệnh tương tác hoạt động khác nhau chủ yếu là do biến bash?
Kiwy

@Kiwy Biến môi trường?
devnull

2
@terdon Bash phân tích toàn bộ khối lệnh trước khi đánh giá bất kỳ khối nào. A ;không làm cho lệnh trước được đánh giá . Như vậy, trình phân tích cú pháp sẽ gặp phải một lệnh không xác định.
devnull

6

Vâng, &&là điều kiện. Lệnh phía sau sẽ chỉ được bắt đầu nếu lệnh trước đó trả về 0(kết thúc mà không có lỗi). Mặt khác, tập lệnh của bạn không có điều khiển này, vì vậy, vd. wget kết thúc với lỗi nó sẽ tiếp tục và cố gắng giải nén và không di chuyển gì cả ..

Trực tuyến cho kịch bản của bạn là:

wget http://something.com ; unzip something ; mv -f something /home/poney/

nào semi colontrong trường hợp này cũng giống như các jumpline trong kịch bản của tôi không?
Kiwy

@Kiwy, đúng vậy.
Graeme

2

Một điểm khác biệt so với cái được đề cập là tập lệnh shell của bạn chạy trong một shell riêng, do đó mọi thay đổi đối với môi trường sẽ không lan truyền. Ví dụ: nếu bạn nhập vào vỏ tương tác của bạn

test -f foo && file=foo || file=other

sau đó, vỏ tương tác của bạn sẽ chứa một biến file(mà bạn có thể đọc cùng $file) chứa foonếu tệp foo tồn tại và là một tệp thông thường, và othernếu không. Bây giờ nếu bạn đặt cùng một tập lệnh shell và gọi nó từ shell tương tác của bạn, thì biến filetrong shell tương tác của bạn sẽ không được đặt (nhưng tất nhiên bên trong tập lệnh shell của nó sẽ được đặt, vì vậy bạn có thể sử dụng nó trong các lệnh tiếp theo trong đó).

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.