Cách sử dụng Bash cho sh trong Ubuntu


13

Tôi đang cài đặt một chương trình lớn, có tài nguyên dưới dạng rpmtệp. Nó bị kẹt ở dòng

#!/bin/sh
SCITEGICPERLBIN=`dirname $0`
SCITEGICPERLHOME=`dirname $SCITEGICPERLBIN`
if [ $SCITEGICPERLHOME == "." ]

Rõ ràng, shhoạt động bashtrong Red Hat Linux với cú pháp này, nhưng nó gây ra lỗi unexpected operatortrong Ubuntu.

Tôi không thể thay đổi tập lệnh thành bashtập lệnh đến từ rpmgói. Tôi có thể trích xuất và đóng gói lại rpmgói, nhưng có thể có nhiều tập lệnh như vậy.

Có cách nào để thay đổi mặc định shell để coi #!/bin/shnhư bashhoặc bất cứ điều gì khác, có thể xử lý [toán tử không?


5
Điều duy nhất sai là ==điều đó nên được =. Điều đó, và rằng các mở rộng biến nên được trích dẫn gấp đôi.
Kusalananda

4
[không phải là một toán tử, mà là một lệnh dựng sẵn được gọi test. Toán tử bất ngờ là ==và điều này nên được thay thế bởi =vì nó không tuân thủ POSIX.
schily

Điều duy nhất thứ hai sai là $SCITEGICPERLHOMEcần được trích dẫn.
l0b0

12
Bạn nên khiếu nại với tác giả của chương trình. Nếu họ sử dụng #!/bin/sh, họ nên đảm bảo rằng họ chỉ sử dụng các tính năng vỏ POSIX, không phải các bashtiện ích mở rộng. Lập trình viên này rất cẩu thả. Anh ta nên sửa mã của mình hoặc sử dụng #!/bin/bash.
Barmar

Đối với những người thắc mắc về các vấn đề tương tự khác ở đây là một danh sách " Bashism ". Cũng xem câu hỏi này .
Thuyền trưởng Man

Câu trả lời:


21

Có nhiều chương trình thực hiện ngôn ngữ của /bin/sh. Trên Ubuntu, /bin/shdash, được thiết kế để nhanh, sử dụng một lượng bộ nhớ nhỏ và không hỗ trợ nhiều hơn mức tối thiểu dự kiến /bin/sh. Trên RHEL, /bin/shlà bash, chậm hơn và sử dụng nhiều bộ nhớ hơn nhưng có nhiều tính năng hơn. Một trong những tính năng này là ==toán tử cho [cú pháp có điều kiện. Dash hỗ trợ [, là một tính năng sh cơ bản, nhưng nó không có ==toán tử là phần mở rộng bash (và ksh và zsh).

Bạn có thể chuyển hệ thống của bạn sang sử dụng bash. Trên Ubuntu, /bin/shlà một liên kết tượng trưng đến dash. Bạn có thể làm cho nó một liên kết tượng trưng để bashthay thế. Các phiên bản hiện tại của Debian và Ubuntu (và các dẫn xuất) làm cho điều này trở thành một tùy chọn cài đặt dấu gạch ngang. Để thay đổi nó, hãy chạy

sudo dpkg-reconfigure dash

và trả lời, vâng, vâng, tiếp tục /bin/shchuyển sang bash.

Bạn có thể giữ bash như /bin/sh, nhưng nó sẽ làm cho hệ thống của bạn chậm hơn một chút. Thậm chí có thể hình dung rằng một số tập lệnh hệ thống không tương thích với bash, mặc dù điều đó không thể xảy ra vì bash chủ yếu là một siêu tập hợp.


Đối với các bản phân phối không có giao diện để lựa chọn giữa các lần triển khai /bin/sh, đây là cách chuyển sang bash.

sudo ln -s bash /bin/sh.bash
sudo mv /bin/sh.bash /bin/sh

Giữ một thiết bị đầu cuối mở và kiểm tra xem bạn vẫn có thể chạy một số shtập lệnh sau đó. Nếu bạn làm hỏng lệnh này, nó sẽ làm cho hệ thống của bạn không thể sử dụng được. (Nhân tiện, lý do tôi sử dụng nhiều lệnh ở trên thay vì nhìn đơn giản sudo ln -sf bash /bin/shlà đó ln -sfkhông phải là nguyên tử. Trong trường hợp không thể thừa nhận, máy tính của bạn bị hỏng trong thao tác này, bạn cần khởi động từ phương tiện cứu hộ để khôi phục nó. Ngược lại, mvlà nguyên tử.)

Để khôi phục dấu gạch ngang như /bin/sh:

sudo ln -s dash /bin/sh.dash
sudo mv /bin/sh.dash /bin/sh

Lưu ý rằng nếu sh /bin/bashtheo mặc định trên bản phân phối của bạn, việc chuyển sang dấu gạch ngang có thể khiến tập lệnh không thành công, vì bash có nhiều tính năng hơn dấu gạch ngang. Các tập lệnh Bash nên bắt đầu bằng #!/bin/bashvà các tập lệnh bắt đầu #!/bin/shkhông nên sử dụng các tính năng dành riêng cho bash, nhưng các bản phân phối đi kèm với bash vì /bin/shcó thể sử dụng các tính năng dành riêng cho bash trong #!/bin/shcác tập lệnh dành riêng cho bản phân phối đó (miễn là người dùng không mong đợi có thể chuyển sang dấu gạch ngang /bin/shvà không có hy vọng rằng các tập lệnh này hoạt động trên bản phân phối khác).


Theo ý kiến ​​không khiêm tốn của tôi, nếu một số tập lệnh thất bại khi /bin/shlà Bash, thì đó là một lỗi trong hệ thống (gói với tập lệnh) hoặc trong sh-mode của Bash . Giống như Stephen nói, hệ thống rõ ràng cho phép thiết lập /bin/shlại Bash, thông qua dpkg-reconfigure. Nó cũng được nhắc đến như một khả năng trong wiki Ubuntu về vấn đề này: wiki.ubuntu.com/DashAsBinSh
ilkkachu

5
@ilkkachu Có, nếu một kịch bản thất bại nếu bị lỗi /bin/sh, đó là một lỗi. Tuy nhiên, lỗi xảy ra. Tôi khuyên bạn nên giữ mặc định nếu bạn không có khả năng và sẵn sàng chẩn đoán các lỗi đó vì những người khác đã kiểm tra nó cho bạn. Tôi đã sử dụng dấu gạch ngang như /bin/shtrước khi nó được hỗ trợ chính thức trên Debian, nhưng đây là một rủi ro tôi gặp phải, vì biết rằng tôi có thể đối phó nếu có chuyện gì xảy ra.
Gilles 'SO- ngừng trở nên xấu xa'

Lưu ý rằng các liên kết được ghi đè thủ công sẽ được khôi phục thành bất kỳ cấu hình nào được lưu trữ trong debconflần tiếp theo dashđược cập nhật; thừa nhận điều này sẽ không xảy ra thường xuyên (nếu có, trong một bản phát hành nhất định) cho các hệ thống chạy Debian ổn định.
Stephen Kitt

36

Để chuyển shsang bash(thay vì dashmặc định), cấu hình lại dash(vâng, nó hơi phản trực giác):

sudo dpkg-reconfigure dash

Điều này sẽ hỏi bạn có muốn dashtrở thành hệ thống mặc định hay không; answer No No ( Tabsau đó Enter) và bashsẽ trở thành mặc định thay vào đó ( tức là /bin/sh sẽ trỏ đến /bin/bash).


1
Giải pháp của bạn thực sự là giải pháp hợp lý nhất, nhưng tôi đã chấp nhận một câu trả lời khác vì các mô tả chi tiết làm rõ vấn đề. Xin lỗi đã làm phiền.
Googlebot

@Googlebot không cần phải xin lỗi, chọn câu trả lời được chấp nhận là đặc quyền của người hỏi. Và tôi đã nhận được một huy hiệu vàng từ nó ;-).
Stephen Kitt
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.