Có thể đọc đầu vào của người dùng từ STDIN trong khi làm rối khối nguồn không?


10

Có thể đọc đầu vào của người dùng từ STDIN trong khi làm rối khối nguồn org-babel-tanglekhông?

Tôi biết điều này: Org Mode Babel - Đánh giá khối mã tương tác .

Điều đó không giúp giải quyết trường hợp sử dụng cụ thể này, vì nó vẫn không cho phép nhập STDIN thích hợp từ shell, mà chỉ mô phỏng một đầu vào hạn chế bên trong cho Emacs.

Lý lịch

Tôi muốn sử dụng Org's Babel để học các ngôn ngữ lập trình mới (Perl và Bash) bằng cách thực hiện một số hướng dẫn từ một tệp org.

Vấn đề là nhiều hướng dẫn dựa vào STDIN. Ví dụ: nếu một người chạy đoạn mã perl sau:

#+BEGIN_SRC perl :tangle hello-name.pl  :results output :export code
use 5.010;
use strict;
use warnings;

say "What is your name?";
my $name=<STDIN>;
say "Hello $name, how are you?";

#+END_SRC

Emacs sẽ không chờ tương tác của người dùng nhập đúng tên trên STDIN và nó sẽ ngay lập tức xuất ra:

#+RESULTS:
: What is your name?
: Hello , how are you?

Điều tương tự bằng cách sử dụng một ví dụ bash. Điều này:

#+BEGIN_SRC sh  :results output :export code :tangle dir-input.sh
#!/bin/bash

if [ -z "$TEST_DIR" ]
then
    echo "TEST_DIR was not set, please enter the path: "
    read input_variable
    export TEST_DIR=$input_variable
fi
#+END_SRC

Sẽ không chờ người dùng nhập vào và Emacs sẽ trả lại ngay lập tức:

#+RESULTS:
: TEST_DIR was not set, please enter the path: 

Có cách nào để Emacs đợi đầu vào trên một khối rối không?

Nếu không, bạn vui lòng cung cấp một số gợi ý về cách viết một cái gì đó giống như một tangle-and-run-via-shell-bufferchức năng:

  • Làm rối khối mã tại điểm, lưu với tên tệp đã cho,
  • thực hiện các tập tin tương ứng trong một shellbộ đệm có thể nhìn thấy ,
  • có thể chấp nhận đầu vào từ người dùng,
  • và cuối cùng báo cáo STDOUT, nếu có, để #+RESULTS:?

Nếu tính năng này không được triển khai (chưa) trong Org, làm thế nào người ta có thể thực hiện nó với elisp?


Cập nhật: Sau khi tìm kiếm và nghiên cứu thêm các hướng dẫn sử dụng Emacs và elisp, có vẻ như cách để làm điều đó sẽ thúc đẩy Comint , như có lẽ make-comint-in-buffer.

(make-comint-in-buffer "*cmd-buffer*" nil "perl" nil "hello-name.pl")

Thật không may, điều đó qua đầu tôi ngay bây giờ

Câu trả lời:


4

Thử cái này xem sao

Lưu ý : Thực hiện các thay đổi nhỏ sau cho khối mã của bạn:

  • Đã chuyển #!/bin/bashvào tiêu đề khối mã :shebang #!/bin/bashđể tự động đặt quyền truy cập tệp thực thi khi khối bị vướng vào dir-input.sh.

  • Đã thêm mã gỡ lỗi để hiển thị $TEST_DIRđược gán chính xác từ read input_variable.

#+BEGIN_SRC sh  :results output :export code :tangle dir-input.sh :shebang #!/bin/bash

if [ -z "$TEST_DIR" ]
then
    echo "TEST_DIR was not set, please enter the path: "
    read input_variable
    export TEST_DIR=$input_variable
    echo "# export TEST_DIR=$TEST_DIR"
fi
#+END_SRC   

Sau đó tạo khối mã mới để gọi tập tin rối ./dir-input.sh.

#+BEGIN_SRC sh :results output :shebang #!/bin/bash  :var USER_INPUT=(read-string "Test Dir: ")
  echo $USER_INPUT | ./dir-input.sh 
#+END_SRC

Tiêu đề thông báo :var USER_INPUT=(read-string "Test Dir: ")

Tiêu đề này sẽ hiển thị Test Dir:lời nhắc trong minibuffercửa sổ khi khối mã được thực thi bằng cách sử dụng a C-c C-c.

Nhập đường dẫn, ví dụ / path / to / test / dir enter

và khối sẽ chuyển đầu vào cho ./dir-input.shqua STDIN. Bạn nên xem như sau#+RESULTS:

#+RESULTS:
: TEST_DIR was not set, please enter the path: 
: # export TEST_DIR=/path/to/test/dir

Hy vọng rằng đã giúp!


Mã được thử nghiệm với:
GNU Emacs 24.4.1 (x86_64-apple-darwin14.0.0, NS apple-appkit-1343,14) của
phiên bản chế độ org 2014-12-25 : 8.3.2


Điều đó giúp khá nhiều, cảm ơn bạn. Một cách sáng tạo của việc sử dụng vars, rất hướng dẫn. Tôi tự hỏi làm thế nào tôi có thể chụp STDIN "toàn bộ", nói chuyện, tức là giống như người ta có thể từ vỏ tự nhiên? Ví dụ: để có thể đọc các dòng mới và kiểm soát ký tự (bên cạnh CTRL-D)?
gsl

1
@gsl - BTW - Tôi vẫn đang nghiên cứu một câu trả lời mới cho câu hỏi về nhiều dòng và ký tự điều khiển. Nếu bạn tìm ra nó trước khi tôi làm ơn xin vui lòng gửi câu trả lời của bạn.
Melioratus

Cảm ơn bạn rất nhiều vì đã chuẩn bị một câu trả lời mới. Tôi vẫn đang xem xét một giải pháp làm việc. Tôi không thể tự mình tìm ra nó, vẫn ở trên đầu tôi ngay bây giờ. Tôi đang chọn câu trả lời của bạn, và khi câu trả lời mới của bạn xuất hiện, hãy chọn nó sau.
gsl

Xin chào @melioratus - bạn có thể tìm ra cách để đối phó với nhiều dòng và ký tự điều khiển không? Điều đó sẽ khá hữu ích trong nhiều trường hợp.
gsl

1
@gsl - Cảm ơn đã theo dõi! Bạn đang đọc chính xác từ stdin sẽ thực sự hữu ích và tôi vẫn đang tìm kiếm! Tôi đã thực hiện đọc tiến trình stdin vào bộ đệm có tên từ dòng lệnh và sau đó gọi elisp để đọc bộ đệm đa dòng thành biến. Điều này hoạt động khi đọc từ một đường ống nhưng tiếc là không phát trực tuyến stdin, tức là tail file |hoạt động nhưng không tail -f file |. Tôi sẽ xem qua các ghi chú của tôi và thêm ví dụ đa dòng hoạt động một phần của tôi làm câu trả lời mới. Cảm ơn đã nhắc nhở!
Melioratus
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.