Tôi đã viết một kịch bản đơn giản. Khi tôi chạy sh <myscriptname.sh>
, tôi đã nhận được đầu ra chính xác, nhưng khi tôi chạy ./<myscriptname.sh>
, tôi đã gặp lỗi.
Sự khác biệt giữa khi tôi làm sh
và là ./
gì?
Tôi đã viết một kịch bản đơn giản. Khi tôi chạy sh <myscriptname.sh>
, tôi đã nhận được đầu ra chính xác, nhưng khi tôi chạy ./<myscriptname.sh>
, tôi đã gặp lỗi.
Sự khác biệt giữa khi tôi làm sh
và là ./
gì?
Câu trả lời:
Khi bạn chạy bất kỳ tập lệnh nào bằng cách chuyển tên tệp cho chương trình trình thông dịch tập lệnh, bạn đang chạy chương trình trình thông dịch với tập lệnh dưới dạng đối số được truyền vào nó. Ví dụ, điều này sẽ giống như quá trình 'sh' với đối số 'filename.sh'. Các sh
thông dịch viên được mở tập tin.
Mặt khác, nếu bạn tự chạy tập lệnh, hệ thống sẽ gọi chương trình thông dịch được chỉ định và nguồn cấp dữ liệu trong nội dung tập lệnh. Trong trường hợp này, quá trình này trông giống như 'filename.sh' không có đối số.
Bạn nên chắc chắn rằng bạn có một dòng bang:
#!/bin/bash
# bash script here
Một dòng bang là dòng đầu tiên trong tập lệnh và bắt đầu với hai ký tự giống nhau #!
, đây là những gì hệ thống đọc khi nó cố thực thi tập lệnh và sau đó hệ thống chuyển tập lệnh đến chương trình ngay sau đó. Lưu ý rằng dòng này không liên quan gì đến bash và cũng hoạt động tốt với python và perl, mặc dù chúng là những ngôn ngữ rất khác nhau. Bạn sẽ sử dụng #!/usr/bin/python
ví dụ và sau đó làm theo nó với mã python.
Khi bạn có tập lệnh của mình, hãy đảm bảo bạn đã đặt quyền thực thi:
chmod a+x filename.sh
Sau đó, bạn có thể chạy tập lệnh theo quy trình riêng của mình:
./filename.sh
Hoặc đặt tệp vào một vị trí đã biết với tên chương trình đẹp, thích /usr/sbin
và chạy từ mọi nơi:
sudo cp filename.sh /usr/sbin/program-name
program-name
Và đây thực sự là lợi ích thiết thực của việc sử dụng dòng bang với quyền phù hợp - đó là tất cả về triển khai . Rất khó để khiến người dùng chạy tập lệnh nếu họ phải nhớ chương trình nào để chạy tập lệnh. Hãy nhớ đưa ra một đường dẫn đầy đủ đến tập lệnh mỗi lần họ muốn chạy nó. /usr/local/bin
Ví dụ như đặt nó vào , và làm cho nó có thể thực thi được, có thể tiết kiệm rất nhiều đau buồn cho những người đang cố gắng sử dụng tập lệnh của bạn. Các chương trình này sau đó trở nên khả dụng cho tất cả người dùng trên máy tính của bạn.
Nó cũng tốt để nhận dạng. Nếu bạn đi vào top
chương trình, một tập lệnh chạy không có dòng bang sẽ chỉ có tên của trình thông dịch tức là bash
, perl
hoặc python
. Nhưng nếu một tập lệnh được chạy với quyền phù hợp, thì tên của tập lệnh sẽ hiển thị.
Lưu ý: Nếu bạn muốn phân phối một tập lệnh có thể truy cập được cho mọi người, thì vui lòng tạo một trang man và gói gỡ lỗi để cài đặt tập lệnh. Chúng ta cần giảm số lượng tập lệnh ngẫu nhiên trực tuyến và tăng số lượng các cuộc tranh luận có thể được gỡ cài đặt.
bash
, không sh
.
PATH
.
/usr/local/bin
có lẽ tốt hơn sau đó /usr/sbin
- nó chỉ ra rằng chương trình là cục bộ của máy này chứ không phải là một phần của phân phối.
Phiên bản ngắn:
sh
là trình thông dịch dòng lệnh (dấu gạch ngang).
Chạy sh my_script
làm cho dash giải thích kịch bản.
./
cố gắng tìm ra trình thông dịch nào sẽ sử dụng, bằng cách nhìn vào dòng đầu tiên. Ví dụ #!/bin/bash
, hoặc thậm chí #!/bin/ruby
(trái ngược với chạy ruby my_script
).
./
tìm thấy bất cứ thứ gì, đó là phương thức thực thi hệ thống nhìn vào hai byte đầu tiên của tệp.
sh
và tập tin chứa sha-bang, điều đó có nghĩa là sha-bang sẽ bị bỏ qua hoặc nó sẽ mở shell nơi sh
liên kết quá và sau đó có thể một số shell khác hoặc nó làm gì :)?
Sự khác biệt bạn làm là,
với sh
, bạn đang chạy một chương trình sẽ diễn giải các dòng trong kịch bản của bạn giống như bạn đã gõ chúng trên dấu nhắc tương tác của thiết bị đầu cuối,
với việc ./
bạn đang tạo một phím tắt giả sử rằng tập lệnh nằm ngay tại thư mục hiện tại bạn đang ngồi VÀ nó sẽ được thực thi (vì ví dụ bạn đã ban hành chmod +x myscript.sh
), giúp bạn tiết kiệm thời gian vô giá cho thời gian trong tương lai :-)
sh
các tập tin không nhất thiết phải được thực thi.
Có ba lý do chính khiến bạn gặp lỗi:
chmod +x <myscriptname.sh>
để sửa nónoexec
") /usr/local/bin
#!
dòng có lỗi #!/bin/sh
hay#!/bin/bash
Nếu dòng đầu tiên của bạn có vẻ đúng nhưng vẫn không hoạt động, hãy đảm bảo tệp không có kết thúc dòng DOS.
Lỗi sẽ trông giống như thế này:
$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory
Bạn có thể sửa nó bằng cách chạy dos2unix <myscriptname.sh>
hoặc nếu bạn không có điều đó ,
perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>
.
Và câu trả lời là sh là tên của vỏ rất phổ biến. Nhưng lỗi thời và được thay thế bởi những người khác. Ngày nay sh được liên kết với các shell khác được cài đặt trên máy. ví dụ tôi đã bash putt ở đó. Chạy bất kỳ shell nào từ sh thường kích hoạt một số chế độ 'tương thích' với hành vi 'shell' ban đầu.
Vì vậy, giải pháp khá đơn giản. Hãy xem những gì đằng sau lệnh sh (ls -al / bin / sh) và đặt #! / Bin / anything_you_find_there làm dòng đầu tiên (hoặc nếu có đoạn mã nào đó trong tập lệnh của bạn chỉnh sửa nó).
Và thay vào đó, có thể có một số lỗi trong chính kịch bản. Giống như sự phụ thuộc được đáp ứng bởi sh, nhưng không phải là thông dịch viên thực sự được sử dụng.
mkdir ~/bin ; cp myscript.sh ~/bin/
echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ;
Không /usr/sbin
, đó là cho các công cụ quản trị không thiết yếu, /usr/local/bin
là lựa chọn tốt hơn nếu bạn không muốn có ~/bin/
, nhưng nên tránh sudo
càng nhiều càng tốt.
~/.profile
đã có mã để thêm ~/bin
, nếu nó tồn tại, thành PATH
. Một lưu ý khác, đừng đặt phần mở rộng lên các tập lệnh.
ls ~/bin/|wc -l = 428
) Tôi đặt rất nhiều thứ trong đó;)
/bin
và /usr/bin
bạn sẽ thấy chúng không sử dụng tiện ích mở rộng.