Set -e có nghĩa là gì trong tập lệnh bash?

787
AndreaNobili 2013-10-28 09:06.

Tôi đang nghiên cứu nội dung của tệp preinst này mà tập lệnh thực thi trước khi gói đó được giải nén khỏi tệp lưu trữ Debian (.deb) của nó.

Tập lệnh có mã sau:

#!/bin/bash
set -e
# Automatically added by dh_installinit
if [ "$1" = install ]; then
   if [ -d /usr/share/MyApplicationName ]; then
     echo "MyApplicationName is just installed"
     return 1
   fi
   rm -Rf $HOME/.config/nautilus-actions/nautilus-actions.conf
   rm -Rf $HOME/.local/share/file-manager/actions/*
fi
# End automatically added section

Truy vấn đầu tiên của tôi là về dòng:

set -e

Tôi nghĩ rằng phần còn lại của tập lệnh khá đơn giản: Nó kiểm tra xem trình quản lý gói Debian / Ubuntu có đang thực hiện thao tác cài đặt hay không. Nếu có, nó sẽ kiểm tra xem ứng dụng của tôi vừa được cài đặt trên hệ thống hay chưa. Nếu có, tập lệnh sẽ in thông báo "MyApplicationName vừa được cài đặt" và kết thúc ( return 1có nghĩa là kết thúc bằng một "lỗi", phải không?).

Nếu người dùng đang yêu cầu hệ thống gói Debian / Ubuntu cài đặt gói của tôi, thì tập lệnh cũng xóa hai thư mục.

Điều này là đúng hay tôi đang thiếu một cái gì đó?

8 answers

860
Gilles Quenot 2013-10-28 09:39.

Từ help set:

  -e  Exit immediately if a command exits with a non-zero status.

Nhưng nó bị một số người coi là thực hành xấu (các tác giả Câu hỏi thường gặp bash và irc freenode #bash Câu hỏi thường gặp). Nó được khuyến khích sử dụng:

trap 'do_something' ERR

để chạy do_somethingchức năng khi xảy ra lỗi.

Xem http://mywiki.wooledge.org/BashFAQ/105

112
Robin Green 2013-10-28 09:14.

set -edừng việc thực thi tập lệnh nếu một lệnh hoặc đường dẫn có lỗi - điều này ngược lại với hành vi trình bao mặc định, là bỏ qua lỗi trong tập lệnh. Nhập help setvào một thiết bị đầu cuối để xem tài liệu cho lệnh tích hợp này.

66
entpnerd 2016-08-06 12:54.

Tôi đã tìm thấy bài đăng này trong khi cố gắng tìm ra trạng thái thoát cho một tập lệnh đã bị hủy bỏ do a set -e. Câu trả lời dường như không rõ ràng đối với tôi; do đó câu trả lời này. Về cơ bản, set -ehủy bỏ việc thực thi một lệnh (ví dụ: tập lệnh shell) và trả về mã trạng thái thoát của lệnh bị lỗi (tức là tập lệnh bên trong, không phải tập lệnh bên ngoài) .

Ví dụ: giả sử tôi có tập lệnh shell outer-test.sh:

#!/bin/sh
set -e
./inner-test.sh
exit 62;

Mã cho inner-test.shlà:

#!/bin/sh
exit 26;

Khi tôi chạy outer-script.shtừ dòng lệnh, tập lệnh bên ngoài của tôi kết thúc bằng mã thoát của tập lệnh bên trong:

$ ./outer-test.sh
$ echo $?
26
57
kenorb 2015-12-21 03:31.

Theo bash - Hướng dẫn sử dụng Set Builtin , nếu -e/ errexitđược đặt, shell sẽ thoát ngay lập tức nếu một đường dẫn bao gồm một lệnh đơn giản , một danh sách hoặc một lệnh ghép trả về trạng thái khác không.

Theo mặc định, trạng thái thoát của đường dẫn là trạng thái thoát của lệnh cuối cùng trong đường dẫn, trừ khi pipefailtùy chọn được bật (tùy chọn này bị tắt theo mặc định).

Nếu vậy, trạng thái trả về của đường ống dẫn của lệnh cuối cùng (ngoài cùng bên phải) để thoát với trạng thái khác 0 hoặc bằng không nếu tất cả các lệnh thoát thành công.

Nếu bạn muốn thực thi điều gì đó khi thoát, hãy thử xác định trap, ví dụ:

trap onexit EXIT

đâu onexitlà chức năng của bạn để làm điều gì đó khi thoát, như bên dưới đang in dấu vết ngăn xếp đơn giản :

onexit(){ while caller $((n++)); do :; done; }

Có tùy chọn tương tự -E/errtrace thay vào đó sẽ bẫy ERR, ví dụ:

trap onerr ERR

Ví dụ

Ví dụ về trạng thái không:

$ true; echo $?
0

Ví dụ về trạng thái khác 0:

$ false; echo $?
1

Ví dụ về trạng thái điều chỉnh:

$ ! false; echo $?
0
$ false || true; echo $?
0

Kiểm tra với pipefailviệc bị vô hiệu hóa:

$ bash -c 'set +o pipefail -e; true | true | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; false | false | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; true | true | false; echo success'; echo $?
1

Kiểm tra với pipefailviệc được bật:

$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1
14
tripleee 2018-12-05 02:04.

Đây là một câu hỏi cũ, nhưng không có câu trả lời nào ở đây thảo luận về việc sử dụng set -eaka set -o errexittrong các tập lệnh xử lý gói Debian. Việc sử dụng tùy chọn này là bắt buộc trong các tập lệnh này, theo chính sách Debian; mục đích rõ ràng là để tránh mọi khả năng xảy ra tình trạng lỗi không được xử lý.

Điều này có nghĩa là trong thực tế, bạn phải hiểu các lệnh bạn chạy trong điều kiện nào có thể trả về lỗi và xử lý từng lỗi đó một cách rõ ràng.

Các lỗi thường gặp là ví dụ diff(trả về lỗi khi có sự khác biệt) và grep(trả về lỗi khi không có kết quả phù hợp). Bạn có thể tránh các lỗi với cách xử lý rõ ràng:

diff this that ||
  echo "$0: there was a difference" >&2
grep cat food ||
  echo "$0: no cat in the food" >&2

(Cũng lưu ý cách chúng tôi cẩn thận đưa tên của tập lệnh hiện tại vào thông báo và viết thông báo chẩn đoán thành lỗi tiêu chuẩn thay vì đầu ra tiêu chuẩn.)

Nếu không có xử lý rõ ràng nào thực sự cần thiết hoặc hữu ích, rõ ràng không làm gì:

diff this that || true
grep cat food || :

(Việc sử dụng :lệnh no-op của shell hơi tối nghĩa, nhưng khá phổ biến.)

Chỉ để nhắc lại,

something || other

là viết tắt của

if something; then
    : nothing
else
    other
fi

tức là chúng tôi nói rõ ràng othernên chạy nếu và chỉ khi somethingthất bại. Longhand if(và các câu lệnh điều khiển luồng shell khác như while, until) cũng là một cách hợp lệ để xử lý lỗi (thực sự, nếu không, các tập lệnh shell với set -ekhông bao giờ có thể chứa các câu lệnh điều khiển luồng!)

Ngoài ra, nói một cách rõ ràng, trong trường hợp không có trình xử lý như thế này, set -esẽ khiến toàn bộ tập lệnh ngay lập tức bị lỗi nếu difftìm thấy sự khác biệt hoặc nếu grepkhông tìm thấy sự phù hợp.

Mặt khác, một số lệnh không tạo ra trạng thái thoát lỗi khi bạn muốn. Các lệnh thường gặp vấn đề là find(trạng thái thoát không phản ánh liệu tệp có thực sự được tìm thấy hay không) và sed(trạng thái thoát sẽ không tiết lộ liệu tập lệnh đã nhận bất kỳ đầu vào nào hoặc thực sự thực hiện bất kỳ lệnh nào thành công hay không). Một biện pháp bảo vệ đơn giản trong một số trường hợp là chuyển đến một lệnh sẽ hét lên nếu không có đầu ra:

find things | grep .
sed -e 's/o/me/' stuff | grep ^

Cần lưu ý rằng trạng thái thoát của một đường ống là trạng thái thoát của lệnh cuối cùng trong đường ống đó. Vì vậy, các lệnh trên thực sự hoàn toàn che giấu trạng thái của findsed, và chỉ cho bạn biết liệu grepcuối cùng có thành công hay không.

(Tất nhiên là có Bash set -o pipefail; nhưng các tập lệnh gói Debian không thể sử dụng các tính năng của Bash. Chính sách này quy định chắc chắn việc sử dụng POSIX shcho các tập lệnh này, mặc dù điều này không phải lúc nào cũng đúng.)

Trong nhiều tình huống, đây là điều cần chú ý riêng khi mã hóa phòng thủ. Đôi khi bạn phải duyệt qua một tệp tạm thời để bạn có thể xem liệu lệnh tạo ra kết quả đó đã hoàn thành thành công hay chưa, ngay cả khi thành ngữ và sự tiện lợi sẽ hướng bạn đến việc sử dụng đường ống dẫn.

14
Kallin Nagelberg 2018-12-15 11:55.

Tôi tin rằng ý định là để kịch bản được đề cập nhanh chóng thất bại.

Để tự kiểm tra điều này, chỉ cần nhập set -evào dấu nhắc bash. Bây giờ, hãy thử chạy ls. Bạn sẽ nhận được một danh sách thư mục. Bây giờ, hãy nhập lsd. Lệnh đó không được nhận dạng và sẽ trả về mã lỗi, và do đó, dấu nhắc bash của bạn sẽ đóng (do set -e).

Bây giờ, để hiểu điều này trong ngữ cảnh của một 'script', hãy sử dụng script đơn giản sau:

#!/bin/bash 
# set -e

lsd 

ls

Nếu bạn chạy nó như cũ, bạn sẽ nhận được danh sách thư mục từ lsdòng cuối cùng. Nếu bạn bỏ ghi chú set -evà chạy lại, bạn sẽ không thấy danh sách thư mục vì bash ngừng xử lý khi nó gặp lỗi từ lsd.

10
Manikandan Raj 2019-05-14 20:46.
Script 1: without setting -e
#!/bin/bash
decho "hi"
echo "hello"
This will throw error in decho and program continuous to next line

Script 2: With setting -e
#!/bin/bash
set -e
decho "hi" 
echo "hello"
# Up to decho "hi" shell will process and program exit, it will not proceed further
0
Miten 2020-10-11 20:30.
cat a.sh
#! /bin/bash

#going forward report subshell or command exit value if errors
#set -e
(cat b.txt)
echo "hi"

./a.sh; echo $?
cat: b.txt: No such file or directory
hi
0

với set -e đã nhận xét ra, chúng tôi thấy rằng trạng thái thoát echo "hi" được báo cáo và hi được in.

cat a.sh
#! /bin/bash

#going forward report subshell or command exit value if errors
set -e
(cat b.txt)
echo "hi"

./a.sh; echo $?
cat: b.txt: No such file or directory
1

Bây giờ chúng tôi thấy lỗi b.txt được báo cáo thay thế và không có chữ hi được in.

Vì vậy, hành vi mặc định của shell script là bỏ qua các lỗi lệnh và tiếp tục xử lý và báo cáo trạng thái thoát của lệnh cuối cùng. Nếu bạn muốn thoát khi bị lỗi và báo cáo trạng thái của nó, chúng tôi có thể sử dụng tùy chọn -e.

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Một thương hiệu kế thừa khác có được cuộc sống mới khi những người chủ mới của Black Opal có được Hội chợ thời trang

Một thương hiệu kế thừa khác có được cuộc sống mới khi những người chủ mới của Black Opal có được Hội chợ thời trang

Desiree Rogers, trái, và Cheryl Mayberry McKissack Chuyển sang, Fenty Beauty và Pat McGrath, có một đế chế làm đẹp mới do phụ nữ làm chủ đang trỗi dậy. Sau thương vụ mua lại mỹ phẩm Black Opal vào tháng 9, đội ngũ quyền lực của Giám đốc điều hành công ty Desiree Rogers và Chủ tịch Cheryl Mayberry McKissack đã thông báo mua lại thương hiệu làm đẹp tiên phong Fashion Fair từ người sáng lập Johnson Publishing Company (JPC).

Ngoài việc trở nên vô nghĩa, các bên bộc lộ giới tính giờ đây đã trở nên chết người

Ngoài việc trở nên vô nghĩa, các bên bộc lộ giới tính giờ đây đã trở nên chết người

Đối với những người có quá nhiều thời gian, tiệc tiết lộ giới tính là một cách thú vị để không cần áp đặt những định kiến ​​hạn chế lên thai nhi trước một đối tượng bạn bè giả vờ quan tâm một cách lịch sự. Tuy nhiên, việc chỉ dựa vào những chiếc bánh nướng có màu nhân tạo để biểu thị một tiếng hoo-ha hoặc một đứa trẻ đi tè đã trở nên xa xỉ trong các bậc cha mẹ trên Instagram.

Kirstjen Nielsen đang cố gắng đổi mới bản thân với tư cách là một người phụ nữ 'nói ra sự thật cho sức mạnh'

Kirstjen Nielsen đang cố gắng đổi mới bản thân với tư cách là một người phụ nữ 'nói ra sự thật cho sức mạnh'

Hôm thứ Tư, cựu Bộ trưởng An ninh Nội địa Kirstjen Nielsen vì một lý do nào đó đã được đưa ra một diễn đàn để phát biểu tại Hội nghị thượng đỉnh Những người phụ nữ quyền lực nhất của Fortune. Và có thể đoán trước được, người phụ nữ giám sát các nỗ lực (đang diễn ra) của chính quyền Trump nhằm chia cắt các gia đình ở biên giới đã sử dụng thời gian của mình như một cơ hội để tự bảo vệ mình và tự nhận mình là người — và hãy hít thở sâu ở đây — “đã nói sự thật với quyền lực.

Toyota Racing Development sẽ cho ra mắt Supra 3000GT Concept, Massive Wing vào tháng tới

Toyota Racing Development sẽ cho ra mắt Supra 3000GT Concept, Massive Wing vào tháng tới

Vì thế hệ mới nhất của chiếc xe điều chỉnh được yêu thích trên thế giới hiện đã có mặt tại đây, nên chỉ có điều kiện là Toyota Racing Development sẽ đưa phiên bản Supra thế hệ thứ năm sửa đổi của riêng mình đến SEMA vào tháng tới. Toyota đã cho chúng tôi một gợi ý về những gì sẽ xảy ra trong tuần này: một chiếc Concept GR Supra 3000GT hiện đại.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language