Khi tôi muốn chạy .sh
các tệp trong Terminal, tôi cần đặt sh
trước chúng.
Có cách nào để tránh điều này, và do đó tiết kiệm gõ?
Khi tôi muốn chạy .sh
các tệp trong Terminal, tôi cần đặt sh
trước chúng.
Có cách nào để tránh điều này, và do đó tiết kiệm gõ?
Câu trả lời:
Nếu bạn đang chạy tập lệnh của mình từ trình bao, bạn thực sự không cần #!/bin/sh
shebang như được nêu trong câu trả lời này , hệ thống giống như Unix mà tôi đã sử dụng, bao gồm cả OS X, sẽ mặc định /bin/sh
nếu không có trình thông dịch cụ thể nào được chỉ định ( mặc dù đó là một ý tưởng tốt vì những người không có vỏ sẽ không biết cách thực thi tập lệnh của bạn trừ khi bạn đưa ra shebang.)
Bạn cũng không cần một .sh
phần mở rộng. Bạn làm cần thiết phải thiết lập quyền thực thi, ví dụ
$ chmod +x script.sh
(Đây $
là dấu nhắc trình bao; Tôi đang sử dụng nó để minh họa các lệnh bạn đưa ra cho trình bao tương tác. Đừng gõ nó!)
Tuy nhiên, tôi nghĩ điều khó hiểu của bạn là bạn đã tạo một tập lệnh, ví dụ script.sh
, trong thư mục hiện tại và đang cố gắng thực thi nó bằng cách chỉ cần gõ script.sh
. ví dụ
$ cat >script.sh
echo hello, world
^D
$ chmod +x script.sh
$ script.sh
-bash: script.sh: command not found
( ^D
có nghĩa là control- D. Bạn sẽ tìm thấy ký hiệu này trong nhiều lần viết về việc sử dụng Unix.)
Thực tế là script.sh
trong trường hợp này là một kịch bản shell chỉ là một nửa vấn đề; Vấn đề thực sự của bạn là theo mặc định, shell sẽ không tìm kiếm thư mục hiện tại cho một chương trình. Tuy nhiên, điều này hoạt động:
$ sh script.sh
hello, world
bởi vì sh
lấy kịch bản làm đối số.
Bạn có thể thực thi một tập lệnh script hoặc, một lần nữa, bất kỳ tập lệnh thực thi nào trong thư mục hiện tại, nếu nó được đánh dấu thực thi (tức là chmod +x
), bằng cách chỉ định rằng bạn muốn chạy tập lệnh trong thư mục hiện tại:
$ ./script.sh
hello, world
Bạn cũng có thể di chuyển tập lệnh đến một thư mục trên của bạn PATH
. Tôi khuyên bạn nên /usr/local/bin
làm điều này nếu tập lệnh của bạn dự định sẽ được sử dụng trên toàn hệ thống hoặc một bin
thư mục trong nhà bạn nếu tập lệnh chỉ dành cho bạn. Cái sau yêu cầu bạn thêm $HOME/bin
, mở rộng vào thư mục bin mới của bạn, PATH
bằng cách thêm các dòng sau vào thư mục chính .profile
của bạn:
PATH=$HOME/bin:$PATH
export PATH
Cuối cùng, bạn có thể, nếu bạn muốn, thực sự thêm thư mục hiện tại vào thư mục của bạn PATH
, điều này sẽ cho phép bạn chỉ cần đi đến một thư mục có chứa script.sh
hay bất kỳ loại thực thi nào khác.
$ script.sh
để thực hiện nó. Tuy nhiên, tôi không khuyến khích thực hành này , vì bây giờ kẻ tấn công có thể lừa bạn chạy một tệp thực thi tùy ý bằng cách thả một tập lệnh thực thi (có tên, giả sử ls
) vào một thư mục mà bạn sẽ tham gia. Tuy nhiên, nếu bạn thực sự muốn làm điều đó chỉ cần thêm những điều sau đây vào .profile
:
PATH=.:$PATH
export PATH
sl
hay lls
hay l
... tức là, lỗi chính tả. Chỉ cần rời .
khỏi $PATH
. Ngoài ra, bạn có thể không (hoặc không nên) nhất thiết phải tin tưởng tất cả mọi người trên hệ thống của mình. Ví dụ: giả sử có một số khai thác cho phép kẻ tấn công thả một tệp tùy ý vào một thư mục nào đó, nhưng chúng cần bạn thực thi tệp đó để chuyển sang khai thác tốt hơn (ví dụ: thu thập dữ liệu và về nhà điện thoại). Phòng thủ chuyên sâu!
/tmp
hoặc một số thư mục có thể ghi trên thế giới khác.
/tmp
et al. đến với lãnh thổ.
Bạn không cần phải gọi sh
nếu tệp script được đánh dấu là có thể thực thi được. Trong trường hợp đó, bạn có thể gọi nó là tên của tôi giống như bất kỳ lệnh nào khác từ shell hiện có.
Để hoàn toàn chính xác, bạn sẽ muốn làm hai điều:
Chỉnh sửa tập lệnh của bạn để bao gồm một lệnh shebang ở đầu tập lệnh của bạn:
#!/bin/sh
... Điều đó sẽ cho trình bao biết trình thông dịch nào sẽ sử dụng để chạy tập lệnh; trong trường hợp này, việc /bin/sh
thực thi
Đánh dấu tập lệnh là tệp thực thi của bạn bằng lệnh chmod :
chmod u+x scriptname.sh
Khi bạn thực hiện cả hai điều đó, bạn sẽ có thể chạy tập lệnh của mình bằng cách nhập tên tệp của tập lệnh vào dòng lệnh. Bạn sẽ cần phải ở cùng thư mục với tập lệnh của mình, trừ khi bạn cũng thực hiện bước bổ sung thêm thư mục chứa vào biến PATH của mình . Nếu bạn không quan tâm shell nào chạy tập lệnh, bạn không cần bước một để chỉ định sh
nhưng thường chính xác hơn là đặt "shebangsh".
/bin/sh
, mặc dù chúng không bị tổn thương.
ksh
kịch bản từ thời còn trên HP-UX - nhưng thật tốt khi biết rằng điều đó không thực sự cần thiết.
exec
syscall, bạn nhận được ENOEXEC
(lỗi định dạng exec ). Xin lỗi về điều đó, @bmike, @ ChrisW.Rea. Tôi sẽ đi chỉnh sửa câu trả lời của tôi bây giờ.