Có sự khác biệt thực tế nào giữa việc chạy tập lệnh với
[sudo] sh ./<script>.run
thay vì
[sudo] chmod +x ./<script>.run
[sudo] ./<script>.run
Có sự khác biệt thực tế nào giữa việc chạy tập lệnh với
[sudo] sh ./<script>.run
thay vì
[sudo] chmod +x ./<script>.run
[sudo] ./<script>.run
Câu trả lời:
Nếu bạn dùng
sh ./<script>.run
/bin/sh
(thường là shell Bourne) sẽ được sử dụng để chạy tập lệnh. Tất nhiên điều này chỉ hoạt động nếu kịch bản được viết cho Bourne shell. Đôi khi các tập lệnh shell cho Linux yêu cầu Bash thay vì shell Bourne, vì vậy điều này có thể không hoạt động ngay cả khi nó là tập lệnh shell.
Nếu bạn dùng
./<script>.run
hạt nhân nhìn vào dòng shebang để tìm ra chương trình nào sẽ sử dụng để chạy chương trình. Vì vậy, điều này hoạt động ngay cả khi nó là Bash, Perl, Python hoặc một số tập lệnh khác.
Vì vậy, đây thường là cách ưa thích để chạy một kịch bản.
Miễn là nó là một sh
kịch bản shell (Dash, hoặc tương đương), không, không có sự khác biệt bên ngoài.
Vấn đề là .run
không đảm bảo đó là trường hợp. Nó có thể là nhị phân. Nó có thể là Bash hoặc Python hoặc PHP hoặc bất cứ điều gì; tất cả chúng đều có mã băm. Nếu bạn mù quáng buộc nó qua sh
, ai biết chuyện gì có thể xảy ra. Nó có thể sẽ bị lỗi nhưng nó có thể vô tình chạy mã độc hại trước khi đi xa đến thế.
Bằng cách chmod
ding nó (để kích hoạt bit quyền thực thi) và sau đó chạy nó ./script.run
, bạn cung cấp cho nó khả năng chạy tốt nhất có thể. Nếu đó là tập lệnh shell, hàm băm của nó sẽ được phân tích cú pháp đúng cách và nếu đó là tập lệnh nhị phân, nó sẽ chỉ chạy tự nhiên.
Hai phương pháp thường có thể hành động giống nhau nhưng rất khác nhau.
sh ./script
chạy sh
lệnh với một đối số ./script
, điều này xảy ra để thực thi tập lệnh đã cho .. ngay cả khi tập lệnh không thực sự là sh
tập lệnh (xấu)
./script
thực hiện các tập tin đã cho. Nó thực hiện điều này bằng cách tìm kiếm dòng "shebang" để xác định lệnh nào sẽ chạy. Nếu không xác định, nó sử dụng sh
(đôi khi hai phương thức này hoạt động giống nhau), nhưng thường thì một trình thông dịch khác được chỉ định ..
Ví dụ: nếu filename
chứa các mục sau:
#!/usr/bin/python
print "This is a Python script!"
.. sau đó hai lệnh rất khác nhau:
$ sh script
script: line 3: print: command not found
$ chmod +x script
$ ./script
This is a Python script!
Nếu không có dòng shebang, hai cái này giống nhau:
$ cat script
echo "This is an sh script"
$ sh ./script
This is an sh script
$ ./script
This is an sh script
Một sự khác biệt quan trọng là nếu dòng hashbang của bạn có các tham số. Ví dụ: nếu tập lệnh bắt đầu bằng
#!/bin/bash -e
... và bạn chạy nó bên ngoài bằng cách sử dụng sh
hoặc bash
, dòng đó sẽ được hiểu là một nhận xét và bị bỏ qua, vì vậy -e
tham số (thoát khi thất bại) sẽ không được xử lý. Vì vậy, đưa ra các kịch bản sau đây:
#!/bin/bash -e
echo Hello
false
echo goodbye
Đầu ra cho ./script
sẽ chỉ là "Xin chào", nhưng đầu ra cho sh script
sẽ được Hello
theo sau goodbye
, có lẽ không được dự định.
Nhân tiện, đây là lý do tại sao bạn phải luôn sử dụng một set -e
câu lệnh riêng biệt (dù sao đó cũng là một ý tưởng hay - thường xuyên hơn là không, nếu có vấn đề giữa tập lệnh, bạn sẽ không muốn nó bị bỏ qua).