2012-04-03 29 views
15

Hãy xem xét đoạn mã sau:công việc trỏ đến kịch bản (cũng có công việc) được bỏ qua một cách hiệu quả

#!/usr/bin/env python 

import sys 

print "Hello! I've got %r as input." % sys.stdin.read() 

Đây là chmod +x ed kịch bản trong /usr/local/bin/my_interpreter. Và điều này:

#!/usr/local/bin/my_interpreter 

This is intended to be passed "as is" to python script. 

chmod +x tập lệnh cố gắng tận dụng. Nếu tôi echo something | /usr/local/bin/my_interpreter, nó hoạt động tốt, nhưng một khi tôi cố gắng để thực hiện kịch bản trên, nó không thành công với

/Users/modchan/test_interpreter/foo.bar: line 3: This: command not found 

Có vẻ rằng foo.bar được âm thầm chuyển hướng đến bash thay vì kịch bản của tôi. Tôi đang làm gì sai? Làm thế nào để thực hiện công việc này?

+1

So sánh với http://unix.stackexchange.com/a/20895 – moodywoody

+0

@moodywoody, các câu hỏi của imho không giống nhau, nhưng câu hỏi bạn đã liên kết khá thông tin. – toriningen

+0

Tôi không muốn nói rằng câu hỏi là một bản sao - chỉ là các chủ đề khác là thông tin. – moodywoody

Trả lời

11

Có vẻ như Mac OS X yêu cầu thông dịch viên phải là nhị phân chứ không phải một tập lệnh khác. Để làm cho nó hoạt động, thay đổi thông dịch kịch bản thứ hai tới

#!/usr/bin/env /usr/local/bin/my_interpreter 

Nhưng bạn đã có một vấn đề thứ hai ở đây: các nội dung của kịch bản thứ hai sẽ không đi đến stdin của thông dịch viên của nó, nhưng kịch bản tên đường dẫn sẽ được thông qua như là đối số dòng lệnh, ví dụ:

/usr/bin/env /usr/local/bin/my_interpreter /Users/modchan/test_interpreter/foo.bar 

Bạn sẽ đọc các tập tin có tên sys.argv[1] hơn là từ sys.stdin.

+1

Cảm ơn, trước câu trả lời của bạn, tôi đã thử sử dụng '/ usr/bin/env my_interpreter', nhưng không biết tên tập tin đi đến argv thay vì stdin. – toriningen

3

Điều này phụ thuộc vào trình tải chương trình của hệ điều hành bạn đang chạy, mà tôi lấy là OS X từ thẻ của bạn. Nhiều hệ điều hành giống UNIX yêu cầu trình thông dịch shebang là một tệp nhị phân thực thi được biên dịch, không phải là một tập lệnh khác với một shebang khác.

http://en.wikipedia.org/wiki/Shebang_(Unix)

Linux đã hỗ trợ này từ 2.6.27.9, nhưng tác giả của bài viết này cho thấy rằng có lẽ không phải là bất kỳ Unixen Berkeley có nguồn gốc từ (mà có lẽ sẽ bao gồm OS X) mà làm:

http://www.in-ulm.de/~mascheck/various/shebang/#interpreter-script

Một cách để thực hiện những gì bạn muốn sẽ là một cái gì đó như thế này:

$!/bin/sh 
exec /usr/local/bin/my_interpreter <<EOM 

... content to be executed ... 
EOM 

Một cách khác sẽ là một cái gì đó như thế này:

$!/usr/bin/env /usr/local/bin/my_interpreter 
... content to be executed ... 
Các vấn đề liên quan