2009-04-09 23 views

Trả lời

846

Để chạy một sh kịch bản phi thực thi, sử dụng:

sh myscript 

Để chạy một bash kịch bản phi thực thi, sử dụng:

bash myscript 

Để bắt đầu thực thi (là bất kỳ tệp nào có quyền thực thi); bạn chỉ cần xác định nó bằng con đường của nó:

/foo/bar 
/bin/bar 
./bar 

Để thực hiện một kịch bản thực thi, cung cấp cho nó sự cho phép cần thiết:

chmod +x bar 
./bar 

Khi một tập tin được thực thi, các kernel có trách nhiệm tìm hiểu làm thế nào để thực hiện nó. Đối với các chương trình không phải nhị phân, điều này được thực hiện bằng cách xem dòng đầu tiên của tệp. Nó nên chứa một hashbang:

#! /usr/bin/env bash 

Các hashbang nói với kernel những gì chương trình để chạy (trong trường hợp này lệnh /usr/bin/env đang chạy với lập luận bash). Sau đó, kịch bản được chuyển đến chương trình (như đối số thứ hai) cùng với tất cả các đối số bạn đã cung cấp kịch bản làm đối số tiếp theo.

Điều đó có nghĩa là mọi tập lệnh có thể thực thi phải có mã băm. Nếu không, bạn không nói hạt nhân nó là gì và do đó hạt nhân không biết chương trình nào sẽ sử dụng để diễn giải nó. Có thể là bash, perl, python, sh hoặc thứ khác. (Trong thực tế, hạt nhân thường sẽ sử dụng trình bao mặc định của người dùng để giải thích tệp, điều này rất nguy hiểm vì nó có thể không phải là trình thông dịch đúng hoặc có thể phân tích cú pháp của nó nhưng với những khác biệt hành vi tinh tế như trường hợp giữa shbash).

Lưu ý về /usr/bin/env

Phổ biến nhất, bạn sẽ thấy tóc mái băm như vậy:

#!/bin/bash 

Kết quả là hạt nhân sẽ chạy chương trình /bin/bash để giải thích kịch bản. Thật không may, bash không phải lúc nào cũng được giao hàng theo mặc định và không phải lúc nào cũng có sẵn trong /bin. Trong khi trên các máy Linux, thông thường, có một loạt các máy POSIX khác nơi các tàu bash ở các địa điểm khác nhau, chẳng hạn như /usr/xpg/bin/bash hoặc /usr/local/bin/bash.

Để viết tập lệnh bash di động, do đó chúng tôi không thể dựa vào mã hóa cứng vị trí của chương trình bash. POSIX đã có cơ chế để xử lý điều đó: PATH. Ý tưởng là bạn cài đặt các chương trình của bạn vào một trong các thư mục có trong PATH và hệ thống sẽ có thể tìm thấy chương trình của bạn khi bạn muốn chạy chương trình theo tên.

Đáng buồn thay, bạn không thể chỉ làm điều này:

#!bash 

Các hạt nhân sẽ không (một số có thể) thực hiện tìm kiếm PATH cho bạn. Tuy nhiên, có một chương trình có thể thực hiện tìm kiếm PATH cho bạn, được gọi là env. May mắn thay, gần như tất cả các hệ thống đều có một chương trình env được cài đặt trong /usr/bin. Vì vậy, chúng ta bắt đầu env sử dụng một đường dẫn cứng, sau đó thực hiện một tìm kiếm PATH cho bash và chạy nó để nó có thể giải thích kịch bản của bạn:

#!/usr/bin/env bash 

Cách tiếp cận này đã một nhược điểm: Theo POSIX, các hashbang thể có một đối số. Trong trường hợp này, chúng tôi sử dụng bash làm đối số cho chương trình env. Điều đó có nghĩa là chúng tôi không còn chỗ để chuyển đối số cho bash. Vì vậy, không có cách nào để chuyển đổi một cái gì đó như #!/bin/bash -exu để chương trình này. Bạn sẽ phải đặt set -exu sau băm thay vào đó.

Cách tiếp cận này cũng có ưu điểm khác: Một số hệ thống có thể giao hàng với /bin/bash, nhưng người dùng có thể không thích, có thể thấy lỗi hoặc lỗi thời và có thể đã cài đặt bash riêng của mình ở một nơi khác. Đây thường là trường hợp trên OS X (Mac), nơi Apple gửi một lỗi thời /bin/bash và người dùng cài đặt một cập nhật /usr/local/bin/bash bằng cách sử dụng một cái gì đó như Homebrew. Khi bạn sử dụng phương thức env thực hiện tìm kiếm PATH, bạn sẽ xem xét tùy chọn của người dùng và sử dụng dấu gạch chéo ưa thích của mình trên hệ thống mà hệ thống của anh ấy đã đi kèm.

+54

Cảm ơn bạn đã dành thời gian để viết một câu trả lời hay cho một câu hỏi đơn giản. –

+4

Nếu tôi sử dụng 'zsh' làm vỏ của mình, tôi có sử dụng' hashbang' '#!/usr/bin/env zsh'? – stefmikhail

+4

@stefmikhail: Không cần biết thông dịch viên shell nào bạn sử dụng để * gọi * tập lệnh, bạn nên sử dụng '#!/usr/bin/env zsh' nếu (và chỉ nếu) mã * bên trong * tập lệnh sẽ được thực hiện bởi trình bao Z. – Johnsyweb

71

Để bắt đầu vỏ kịch bản 'file.sh':

sh file.sh 

bash file.sh 

Một lựa chọn khác được thiết lập cho phép thực thi sử dụng lệnh chmod:

chmod +x file.sh 

Bây giờ chạy sh tập tin như sau:

./file.sh 
+0

tnx guys đã giúp tôi tìm hiểu một lệnh mới – Dinakar

+0

Cảm ơn, cho phép thực thi giải quyết vấn đề của tôi :) – htafoya

11

Đối với vỏ bourne:

sh myscript.sh 

Đối với bash:

bash myscript.sh 
+0

Cảm ơn bạn đã trả lời câu hỏi khá rõ ràng này. Đối với một anh chàng Mac như tôi, rất dễ quên các lệnh Unix cũ giữa các vòng. –

10

Nếu bạn muốn kịch bản để chạy trong vỏ hiện tại (ví dụ như bạn muốn nó có thể ảnh hưởng đến thư mục hoặc môi trường của bạn), bạn nên nói:

. /path/to/script.sh 

hoặc

source /path/to/script.sh 

Note rằng /path/to/script.sh có thể là tương đối, ví dụ . bin/script.sh chạy script.sh trong thư mục bin trong thư mục hiện tại.

+6

Hãy ** rất cẩn thận khi tìm nguồn cung ứng hoặc chấm điểm với các tên đường dẫn có liên quan. Bạn nên ** luôn luôn ** bắt đầu chúng với ./ Nếu bạn không làm điều này, và đường dẫn tương đối không chứa bất kỳ dấu gạch chéo, bạn sẽ tìm nguồn cung cấp một cái gì đó trong PATH, TRƯỚC một cái gì đó trong thư mục hiện hành! Rất nguy hiểm cho việc lạm dụng. – lhunath

0

Thứ nhất, cho phép để thực hiện: -
chmod +x script_name

  1. Nếu kịch bản không phải là thực thi: -
    Để chạy tập tin sh kịch bản: -
    sh script_name
    Để chạy tập tin bash script: -
    bash script_name
  2. Nếu tập lệnh có thể thực thi được: -
    ./script_name

LƯU Ý: -bạn có thể kiểm tra nếu tập tin thực thi hay không bằng cách sử dụng 'ls -a'

0

Các .command phần mở rộng tập tin được gán cho Terminal.app. Nhấp đúp vào bất kỳ tệp .command nào sẽ thực thi nó.

Các vấn đề liên quan