2011-02-01 23 views
11

Tôi muốn thực hiện lệnh shell sau trong emacs-lisp:Trong Emacs-lisp, cách chính xác để sử dụng quá trình gọi trên lệnh ls là gì?

ls -t ~/org *.txt | head -5 

nỗ lực của tôi tại như sau:

(call-process "ls" nil t nil "-t" "~/org" "*.txt" "| head -5") 

kết quả trong

ls: ~/org: No such file or directory 
ls: *.txt: No such file or directory 
ls: |head -5: No such file or directory 

Bất kỳ trợ giúp sẽ được đánh giá cao .

Trả lời

16

Sự cố là các mã thông báo như ~, *| không được xử lý/mở rộng bởi chương trình ls. Vì mã thông báo không được xử lý, ls tìm kiếm tệp hoặc thư mục có tên là ~/org, một tệp hoặc thư mục được gọi là *.txt và một tệp hoặc thư mục được gọi là | head -5. Vì vậy, thông báo lỗi mà bạn nhận được về "Không có tệp hoặc thư mục như vậy".

Các mã thông báo này được xử lý/mở rộng bởi vỏ (như Bourne shell/bin/sh hoặc Bash/bin/bash). có thể là trình bao cụ thể, nhưng phần lớn trình bao giải thích ít nhất một số mã thông báo giống nhau theo cùng một cách, ví dụ: | có nghĩa là kết nối các chương trình với nhau từ đầu đến cuối cho hầu hết tất cả các trình bao. không làm ~ dấu ngã/mở rộng thư mục nhà

Nếu bạn muốn mở rộng, bạn phải yêu cầu chương trình gọi để tự mở rộng giống như một trình bao (làm việc chăm chỉ) hoặc chạy lệnh ls trong một shell (dễ dàng hơn nhiều):

/bin/bash -c "ls -t ~/org *.txt | head -5" 

nên

(call-process "/bin/bash" nil t nil "-c" "ls -t ~/org *.txt | head -5") 

Edit: làm rõ một số vấn đề, như đề cập rằng /bin/sh không làm ~ mở rộng.

+0

Câu trả lời hoàn hảo. Cảm ơn! – eatloaf

+0

@eatload - gald để có thể trợ giúp - 'shell-command' của R. P. Dillon có vẻ như là một lựa chọn tốt. –

11

Tùy thuộc vào trường hợp sử dụng của bạn, nếu bạn thấy mình muốn thực thi các lệnh trình bao và có sẵn đầu ra trong bộ đệm mới thường xuyên, bạn cũng có thể sử dụng tính năng shell-command. Trong ví dụ của bạn, nó sẽ giống như thế này:

(shell-command "ls -t ~/org *.txt | head -5") 

Để có điều này đưa vào bộ đệm hiện nay, tuy nhiên, sẽ yêu cầu bạn thiết lập current-prefix-arg bằng tay sử dụng một cái gì đó giống như (universal-argument), mà là một chút của một hack. Mặt khác, nếu bạn chỉ muốn đầu ra một nơi nào đó bạn có thể nhận được nó và xử lý nó, shell-command sẽ làm việc cũng như bất cứ điều gì khác.

+1

Tôi không nghĩ bạn cần đặt 'current-prefix-arg' theo cách thủ công. 'shell-command' có hai tham số tùy chọn' output-buffer' và 'error-buffer'. –

+0

Tôi thấy điều đó, nhưng chú ý rằng nếu bạn chỉ rõ 'output-buffer' là bộ đệm hiện tại, nó nói nó xóa bộ đệm trước và sau đó đẩy vào kết quả của lệnh, điều này thường không mong muốn, tôi nghĩ vậy. Tôi đã không thử nó mặc dù, vì vậy tôi không thể nói chắc chắn. –

+0

Nếu bạn muốn đầu ra vào bộ đệm hiện tại, bạn có thể sử dụng đối số không phải là bộ đệm cũng không phải là nil cho 'đầu ra-bộ đệm'.Sau đó, đầu ra sẽ được chèn thay vì thay thế nội dung hiện tại. Ví dụ. '(shell-command" ls "t)' –

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