Phần mở rộng tệp Bash là gì?


82

Tôi đã viết một tập lệnh bash trong một trình soạn thảo văn bản, tôi nên lưu phần mở rộng nào để tập lệnh của mình có thể chạy dưới dạng tập lệnh bash? Tôi đã tạo một tập lệnh về lý thuyết sẽ khởi động một máy chủ ssh. Tôi đang tự hỏi làm thế nào để làm cho tập lệnh thực thi khi tôi nhấp vào nó. Tôi đang chạy OS X 10.9.5.


4
Tập lệnh Shell không yêu cầu bất kỳ phần mở rộng cụ thể nào. Chỉ cần thực hiện nó nhưbash myscript
anubhava

7
Thông thường .sh, nhưng phần mở rộng không bắt buộc phải tồn tại. Linux không phải là Windows. Chương trình sẽ diễn giải tập lệnh của bạn được xác định ở dòng đầu tiên của nó, điều đó phải như vậy #!/bin/bash. Nó thậm chí có thể bao gồm các thông số.
Havenard

1
@anubhava Làm thế nào tôi sẽ nhận được kịch bản của tôi để thực hiện nếu tôi là chỉ để nhấn đúp chuột vào nó và không thực sự gõ "bash myscript"
Amedeo

2
@Amedeo sẽ dẫn tệp của bạn với dòng #!/bin/bash.
Havenard

Câu trả lời:


106

Không đồng ý với các câu trả lời khác, có một quy ước chung là sử dụng .shphần mở rộng cho các tập lệnh shell - nhưng nó không phải là một quy ước hữu ích. Tốt hơn là không sử dụng tiện ích mở rộng nào cả. Lợi thế của việc có thể nói rằng đó foo.shlà một tập lệnh shell vì tên của nó rất nhỏ và bạn phải trả tiền cho nó nếu không có tính linh hoạt.

Để thực thi một tập lệnh bash, nó cần có một dòng shebang ở trên cùng:

#!/bin/bash

và sử dụng chmod +xlệnh để hệ thống nhận dạng nó là một tệp thực thi. Sau đó, nó cần được cài đặt trong một trong các thư mục được liệt kê trong của bạn $PATH. Nếu tập lệnh được gọi foo, bạn có thể thực thi nó từ dấu nhắc trình bao bằng cách nhập foo. Hoặc nếu nó nằm trong thư mục hiện tại (phổ biến cho các tập lệnh tạm thời), bạn có thể nhập ./foo.

Cả shell và hệ điều hành đều không chú ý đến phần mở rộng của tên tệp. Nó chỉ là một phần của cái tên. Và bằng cách không cung cấp cho nó một tiện ích mở rộng đặc biệt, bạn đảm bảo rằng bất kỳ ai (người dùng hoặc một tập lệnh khác) sử dụng nó đều không phải quan tâm đến cách nó được triển khai, cho dù đó là tập lệnh shell (sh, bash, csh hay bất cứ thứ gì) , một tập lệnh Perl, Python hoặc Awk hoặc một tệp thực thi nhị phân. Hệ thống được thiết kế đặc biệt để có thể gọi một tập lệnh được thông dịch hoặc một tệp thực thi nhị phân mà không cần biết hoặc quan tâm đến cách nó được triển khai.

Các hệ thống giống UNIX bắt đầu với giao diện dòng lệnh hoàn toàn là văn bản. Các GUI như KDE và Gnome đã được thêm vào sau đó. Trong hệ thống máy tính để bàn GUI, bạn thường có thể chạy một chương trình (một lần nữa, cho dù đó là tập lệnh hay tệp thực thi nhị phân) bằng cách nhấp đúp vào biểu tượng đề cập đến nó. Thông thường, điều này loại bỏ bất kỳ đầu ra nào mà chương trình có thể in ra và không cho phép bạn chuyển các đối số dòng lệnh; nó kém linh hoạt hơn nhiều so với chạy nó từ một dấu nhắc trình bao. Nhưng đối với một số chương trình (chủ yếu là ứng dụng GUI), nó có thể thuận tiện hơn.

Tập lệnh Shell tốt nhất nên học từ dòng lệnh, không phải từ GUI.

(Một số công cụ làm chú ý đến phần mở rộng tập tin Ví dụ, trình biên dịch thường sử dụng phần mở rộng để xác định ngôn ngữ mã được viết bằng:. .cCho C, .cpp. Cho c ++ vv Công ước này không áp dụng cho các file thực thi)

Hãy nhớ rằng UNIX (và các hệ thống giống UNIX) không phải là Windows. MS Windows thường sử dụng phần mở rộng của tệp để xác định cách mở / thực thi nó. Các tệp thực thi nhị phân cần có .exephần mở rộng. Nếu bạn đã cài đặt trình bao giống UNIX trong Windows, bạn có thể định cấu hình Windows để nhận dạng .shtiện ích mở rộng dưới dạng tập lệnh trình bao và sử dụng trình bao để mở nó; Windows không có #!quy ước.


2
Những gì tôi đang hướng tới là những gì bạn đã đề cập trong đoạn thứ tư. Chạy tập lệnh của tôi khi được nhấp vào biểu tượng đề cập đến nó.
Amedeo

2
@Amedeo: Sau đó, nó phụ thuộc vào môi trường máy tính để bàn của bạn. Trong chương trình tôi sử dụng (Cinnamon trong Ubuntu), nhấp đúp vào biểu tượng của một tập lệnh thực thi sẽ nhắc tôi chạy nó trong một thiết bị đầu cuối, hiển thị nó trong trình chỉnh sửa hoặc chạy nó mà không cần thiết bị đầu cuối. Nó thực hiện điều này bất kể phần mở rộng tệp.
Keith Thompson

3
(Necro) Nếu bạn bỏ qua phần mở rộng, thì bạn không thể có một thư mục cùng tên. Vì vậy, ví dụ, bạn có deploy.sh(hoặc deploy.bash) và một thư mục deploy, với logic triển khai bổ sung. Nếu bạn đổi tên tập lệnh đơn giản, deploynó sẽ gây ra xung đột tên. Đặt tên tệp hoặc thư mục khác nhau sẽ ảnh hưởng đến khả năng quản lý và có thể là sắp xếp tệp ( ls, trong trình chỉnh sửa, v.v.). Tất nhiên, shebang - cuối cùng - là yếu tố quyết định. Nhưng phần mở rộng tệp có vị trí thích hợp.
Kafoso

2
@Kafoso: Tôi không nghĩ rằng mình đã từng cảm thấy cần phải có một tập lệnh và một thư mục có cùng tên. Nếu tôi đã làm vậy, tôi có thể gọi thư mục Deploy, mặc dù điều đó có thể gây ra sự cố khi sao chép vào hệ thống tệp không phân biệt chữ hoa chữ thường.
Keith Thompson

2
Trên máy Mac, nhấp đúp vào tệp luôn mở chúng trong ứng dụng mặc định. Vì vậy, thật hữu ích khi có một .shtiện ích mở rộng để tập lệnh mở trong trình chỉnh sửa mong muốn của bạn. Nếu bạn muốn chạy một tập lệnh khi được nhấp đúp, hãy cung cấp cho nó .commandphần mở rộng và nó sẽ chạy trong Terminal khi được nhấp đúp.
BallpointBen

17

Bạn không cần bất kỳ phần mở rộng nào (hoặc bạn có thể chọn một phần mở rộng tùy ý, nhưng .shlà một quy ước hữu ích).

Bạn nên bắt đầu tập lệnh của mình bằng #!/bin/bash(dòng đầu tiên được hiểu bởi thực thi (2) syscall) và bạn nên làm cho tệp của mình có thể thực thi bằng chmod u+x. vì vậy nếu tập lệnh của bạn nằm trong một số tệp, $HOME/somedir/somescriptname.shbạn cần nhập một lần

 chmod u+x  $HOME/somedir/somescriptname.sh

trong một thiết bị đầu cuối. Xem chmod (1) cho lệnh và chmod (2) cho syscall.

Trừ khi bạn đang nhập toàn bộ đường dẫn tệp, bạn nên đặt tệp đó vào một số thư mục được đề cập trong PATH(xem môi trường (7) & tệp thực thi (3) ), mà bạn có thể đặt vĩnh viễn trong ~/.bashrcnếu trình bao đăng nhập của bạn bash)

BTW, bạn có thể viết tập lệnh của mình bằng một số ngôn ngữ khác, ví dụ như bằng Python bằng cách bắt đầu bằng #!/usr/bin/pythonhoặc trong Ocaml bằng cách bắt đầu bằng #!/usr/bin/ocaml...

Thực thi tập lệnh của bạn bằng cách nhấp đúp (vào cái gì? Bạn chưa nói!) Là một vấn đề môi trường máy tính để bàn và có thể là một máy tính cụ thể (có thể khác với Kde, Mate, Gnome, .... hoặc IceWM hoặc RatPoison). Có lẽ đọc thông số kỹ thuật của EWMH có thể giúp bạn có được bức tranh đẹp hơn.

Có lẽ việc làm cho tập lệnh của bạn chmodcó thể thực thi với có thể làm cho nó có thể nhấp được trên màn hình của bạn (dường như là Quartz trên MacOSX). Nhưng sau đó bạn có thể nên đưa ra một số phản hồi trực quan.

Và một số máy tính không có bất kỳ máy tính để bàn nào, kể cả máy tính của bạn khi bạn truy cập từ xa bằng ssh .

Tôi không tin rằng bạn nên chạy tập lệnh shell của mình bằng cách nhấp chuột. Bạn có thể muốn có thể đưa ra các đối số cho tập lệnh shell của mình (và bạn sẽ làm điều đó như thế nào bằng cách nhấp vào?), Và bạn nên quan tâm đến đầu ra của nó. Nếu bạn có thể viết một kịch bản shell, bạn có thể sử dụng một shell tương tác trong một thiết bị đầu cuối. Đó là cách tốt nhất và tự nhiên nhất để sử dụng script. Các shell tương tác tốt (ví dụ như zsh hoặc fish hoặc có thể là gần đây bash) có các tiện ích tự động hoàn thành tốt và có thể cấu hình và bạn sẽ không phải gõ nhiều (học cách sử dụng tabphím của bàn phím). Ngoài ra, các tập lệnh và chương trình thường là một phần của các lệnh tổng hợp (đường ống dẫn, v.v.).

Tái bút. Tôi đang sử dụng Unix từ năm 1986 và Linux từ năm 1993. Tôi chưa bao giờ bắt đầu các chương trình hoặc tập lệnh của riêng mình bằng cách nhấp chuột. Tại sao phải là tôi?


3
Được rồi, vậy là tôi đã tạo tập lệnh của mình trong trình soạn thảo văn bản. Tôi lưu tệp vào máy tính để bàn của mình. Khi tôi nhấp vào tập lệnh được lưu trên màn hình của tôi, tôi muốn nó thực sự chạy khi tôi nhấp vào nó.
Amedeo

6
Tôi không biết máy tính để bàn của bạn là gì (KDE, Gnome, MATE, ...). Tôi thực sự mời bạn sử dụng dòng lệnh trong một thiết bị đầu cuối, đặc biệt là để chạy các tập lệnh của bạn (bạn có thể muốn cung cấp cho họ một số đối số; bạn sẽ làm điều đó như thế nào trên máy tính để bàn?). Nếu bạn có thể mã hóa một kịch bản shell bạn sẽ có thể sử dụng vỏ tương tác trong một thiết bị đầu cuối
Basile Starynkevitch

2
Quan điểm của tôi là nếu bạn đang viết mã shell script, bạn nên có thói quen sử dụng dòng lệnh trong một thiết bị đầu cuối.
Basile Starynkevitch

2
Tôi hiểu điều đó, đó là cho một dự án tôi đang làm. Tôi muốn tập lệnh thực thi khi được nhấp vào. Tôi đang cố gắng tránh sử dụng thiết bị đầu cuối để chạy tập lệnh.
Amedeo

3
Tôi muốn sử dụng chmod +xhơn là chmod u+x, trừ khi có một lý do cụ thể để hạn chế khả năng thực thi đối với chủ sở hữu.
Keith Thompson

2

Tôi biết điều này bây giờ khá cũ nhưng tôi cảm thấy như thế này thêm vào những gì câu hỏi được yêu cầu.

Nếu của bạn trên máy mac và bạn muốn có thể chạy một tập lệnh bằng cách nhấp đúp vào tập lệnh đó, bạn cần sử dụng .commandtiện ích mở rộng. Cũng giống như trước khi làm cho tệp thực thi với chmod -x.

Như đã nói trước đây, điều này không thực sự hữu ích.


1

chỉ .sh.

Chạy tập lệnh như sau:

./script.sh

CHỈNH SỬA: Giống như anubhava đã nói, phần mở rộng không thực sự quan trọng. Nhưng vì lý do tổ chức, bạn vẫn nên sử dụng tiện ích mở rộng.


6
Nếu bạn đang chạy một tập lệnh, bạn thường không có lý do gì để quan tâm nó được viết bằng gì. Một tập lệnh bash và một tập lệnh nhị phân được thực thi theo cùng một cách. Thêm một .shhậu tố vào một tập lệnh thực thi nói chung là vô ích.
Keith Thompson

1
vâng, nhưng như tôi đã nói trong bản chỉnh sửa của mình - đó là một quy ước để sắp xếp các kịch bản - chứ không phải hơn ?!
Marc Anton Dahmen

4
Tôi thấy rất nhiều tập lệnh có .shphần mở rộng (và ít tập lệnh có phần mở rộng hơn .bash), nhưng tôi không tin rằng nó hữu ích chút nào. Nếu tôi đặt tên cho một tập lệnh foo.shvà sau đó tôi quyết định thực hiện lại nó trong Perl, tôi có thể thay đổi tên (và chỉnh sửa mọi thứ sử dụng nó) hoặc để lại nó với một phần mở rộng gây hiểu lầm. Nếu tôi đặt tên cho nó foo, tôi không có vấn đề đó.
Keith Thompson

1

TL; DR - Nếu người dùng (không nhất thiết là nhà phát triển) tập lệnh đang sử dụng giao diện GUI, điều đó phụ thuộc vào trình duyệt tệp mà họ đang sử dụng. Trình tìm kiếm của MacOS sẽ yêu cầu .shphần mở rộng để thực thi tập lệnh. Gnome Nautilus, tuy nhiên, nhận ra các tập lệnh được phân loại đúng cách có hoặc không có .shphần mở rộng.

Tôi biết người ta đã nói nhiều lần về lý do và không nên sử dụng tiện ích mở rộng trên các tập lệnh bash, nhưng không nhiều lý do tại sao hoặc tại sao không sử dụng tiện ích mở rộng, nhưng tôi có điều mà tôi coi là nguyên tắc chung.

Nếu bạn là kiểu người nhảy vào và ra khỏi bash và sử dụng thiết bị đầu cuối nói chung hoặc đang phát triển một công cụ cho người khác không sử dụng thiết bị đầu cuối, hãy đặt .shphần mở rộng trên các tập lệnh bash của bạn. Bằng cách đó, người dùng tập lệnh đó có tùy chọn nhấp đúp vào tệp đó trong trình duyệt tệp GUI để chạy tập lệnh.

Nếu bạn là kiểu người chủ yếu làm tất cả hoặc hầu hết công việc của bạn trong thiết bị đầu cuối, đừng bận tâm đến việc đặt bất kỳ tiện ích mở rộng nào vào các tập lệnh bash của bạn. Chúng sẽ không phục vụ mục đích nào trong terminal, giả sử rằng bạn đã thiết lập ~/.bashrctệp của mình để phân biệt trực quan các tập lệnh với các thư mục.

Biên tập:

Trong trình duyệt tệp Gnome Nautilus có 4 tệp thử nghiệm (mỗi tệp có quyền được cấp để tệp được thực thi) với lệnh bash đơn giản đến mức ngu ngốc để mở cửa sổ đầu cuối ( gnome-terminal):

  1. Tệp KHÔNG có phần mở rộng với #!/bin/bash trên dòng đầu tiên.

    Nó hoạt động bằng cách nhấp đúp vào tệp.

  2. Một tệp có .sh phần mở rộng #!/bin/bashở dòng đầu tiên.

    Nó hoạt động bằng cách nhấp đúp vào tệp.

  3. Tệp KHÔNG có phần mở rộng với KHÔNG #!/bin/bash ở dòng đầu tiên.

    Nó hoạt động bằng cách nhấp đúp vào tệp ... về mặt kỹ thuật, nhưng GUI không cho thấy đó là một tập lệnh shell. Nó nói rằng nó chỉ là một tập tin văn bản thuần túy.

  4. Một tệp có .sh phần mở rộng là KHÔNG #!/bin/bashtrên dòng đầu tiên.

    Nó hoạt động bằng cách nhấp đúp vào tệp.

Tuy nhiên, như Keith Thompson, trong các bình luận của câu trả lời này, đã chỉ ra một cách khôn ngoan, dựa vào việc sử dụng .sh phần mở rộng thay vì phần bash shebang trên dòng đầu tiên của tệp ( #!/bin/bash) nó có thể gây ra vấn đề.

Tuy nhiên, một điều khác, tôi nhớ lại khi trước đây tôi đang sử dụng MacOS, thậm chí .shkhông thể chạy các tập lệnh bash đúng cách (đó là một từ?) Mà không có phần mở rộng từ GUI trên MacOS. Mặc dù vậy, tôi rất muốn ai đó sửa cho tôi điều đó trong các bình luận. Nếu điều này là đúng, nó sẽ chứng minh rằng có ít nhất một trình duyệt tệp ở đó có .shtiện ích mở rộng quan trọng.


Bạn sử dụng trình duyệt tệp GUI nào (hoặc liên quan hơn, người dùng của bạn sử dụng những gì)? Nó có sử dụng tiện ích mở rộng để quyết định cách chạy một tập lệnh không?
Keith Thompson

Chà, nền tảng mà tôi có nhiều kinh nghiệm nhất là MacOS. Trong Finder, người dùng quyết định ứng dụng nào sẽ liên kết với tiện ích mở rộng nào. Bây giờ, tôi đang sử dụng Linux bằng Gnome, nhưng tôi chưa thử nghiệm cách trình duyệt tệp Nautilus của Gnome tương tác với các tệp không có phần mở rộng.
Ryan Hart

Nếu bạn có một tập lệnh thực thi có .shhậu tố và #!/bin/bashở dòng đầu tiên, liệu trình duyệt tệp GUI sẽ sử dụng shđể gọi nó (bỏ qua shebang)? Nếu vậy, điều đó có thể gây ra một số vấn đề. (Câu trả lời có thể là khác nhau cho các trình duyệt khác nhau.)
Keith Thompson

Điểm tốt ở đó. Tôi đã cập nhật câu trả lời của mình ở trên với một số thử nghiệm thực tế mà tôi đã thực hiện ngay bây giờ.
Ryan Hart

Thật thú vị, nhưng ... Bạn đã nói nó "hoạt động". Đối với mỗi trường hợp trong số 4 trường hợp thử nghiệm, sẽ rất tốt nếu biết liệu nó có gọi nó bằng /bin/bashhoặc hay không /bin/sh(trường hợp sau là mặc định cho một tập lệnh không có shebang). Nếu /bin/shlà một liên kết tượng trưng tới /bin/bash(khá phổ biến) thì bạn có thể biết bằng cách xem giá trị của $0. (Ngoài ra, nếu bash được gọi như shnó đặt POSIXLY_CORRECT=y.)
Keith Thompson
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.