소스 블록을 엉킨 상태에서 STDIN에서 사용자 입력을 읽을 수 있습니까?


10

소스 블록을 엉키면서 STDIN에서 사용자 입력을 읽을 수 org-babel-tangle있습니까?

나는 이것을 알고있다 : 조직 모드 바벨-대화 형 코드 블록 평가 .

쉘에서 적절한 STDIN 입력을 허용하지 않지만 Emacs 내부 에서 제한된 입력 만 시뮬레이션하므로이 특정 사용 사례를 해결하는 데 도움이되지 않습니다 .

배경

조직의 Babel을 사용하여 하나의 조직 파일에서 튜토리얼을 실행하여 새로운 프로그래밍 언어 (Perl 및 Bash)를 배우고 싶습니다.

문제는 많은 튜토리얼이 STDIN에 의존한다는 것입니다. 예를 들어, 다음 perl tidbit를 실행하는 경우 :

#+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는 사용자의 상호 작용 이 STDIN에 이름을 올바르게 입력하기를 기다리지 않고 즉시 출력합니다.

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

bash 예제를 사용하는 것과 같습니다. 이:

#+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

사용자 입력을 기다리지 않고 Emacs는 즉시 다음을 반환합니다.

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

Emacs가 얽힌 실행 블록에서 입력을 기다리는 기본 방법이 있습니까?

그렇지 않다면 다음과 같은 tangle-and-run-via-shell-buffer함수 와 같은 것을 작성하는 방법에 대한 포인터를 제공하십시오 .

  • 주어진 파일 이름으로 저장하여 코드 블록을 엉킴
  • 보이는 shell버퍼 에서 해당 파일을 실행
  • 사용자의 입력을 수락 할 수도 있습니다.
  • 마지막 STDOUT으로 #+RESULTS:?

이러한 기능이 조직에서 아직 구현되지 않은 경우 elisp로 어떻게 구현할 수 있습니까?


업데이트 : 더 많은 Emacs 및 elisp 매뉴얼을 검색하고 연구 한 후에 아마도 Comint를 활용하는 방법이 될 것 같습니다 make-comint-in-buffer.

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

불행히도, 그것은 지금 내 머리 위에 있습니다. 😣

답변:


4

이 시도

참고 : 코드 블록을 다음과 같이 약간 변경했습니다.

  • 블록이 엉 키면 실행 파일 권한을 자동으로 설정하기 위해 #!/bin/bash코드 블록 헤더 로 이동 했습니다 .:shebang #!/bin/bashdir-input.sh

  • $TEST_DIR에서 올바로 할당 된 디버그 코드를 추가 했습니다 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   

그런 다음 얽힌 파일을 호출하는 새 코드 블록을 만들었습니다 ./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

통지 헤더 :var USER_INPUT=(read-string "Test Dir: ")

이 헤더 는를 사용하여 코드 블록이 실행될 때 창에 Test Dir:프롬프트를 표시 minibuffer합니다 C-c C-c.

경로를 입력하십시오 (예 : / path / to / test / dir). enter

블록은 입력을 ./dir-input.shvia에 전달합니다 STDIN. 다음을 볼 수 있습니다#+RESULTS:

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

도움이 되었기를 바랍니다.


: 코드 테스트
2014년 12월 25일의 GNU 이맥스 24.4.1 (x86_64에-사과 darwin14.0.0, NS는 사과 AppKit의-1343.14)
조직 모드 버전 : 8.3.2


꽤 도움이됩니다. 감사합니다. 매우 유익한 vars를 사용하는 창의적인 방법. 나는 어떻게 STDIN "완전한", 즉 일종의 말, 즉 원시 껍질에서 얻을 수있는 것과 같은 것을 포착 할 수 있을지 궁금합니다. 예를 들어, 새로운 행을 읽고 제어 문자 (CTRL-D 옆)를 읽을 수 있습니까?
gsl

1
@gsl-BTW-여러 줄과 제어 문자에 대한 질문에 대한 새로운 답변을 계속하고 있습니다. 내가하기 전에 알아 차리면 답을 게시하십시오.
Melioratus 2016 년

새로운 답변을 준비해 주셔서 감사합니다. 나는 여전히 해결책을 찾고 있습니다. 나는 아직 내 머리 위로, 혼자서 그것을 알아낼 수 없다. 답변을 선택하고 있으며 새로운 답변이 나오면 나중에 선택하십시오.
gsl

안녕하세요 @melioratus-여러 줄을 처리하고 문자를 제어하는 ​​방법을 찾을 수 있었습니까? 많은 경우에 매우 유용합니다.
gsl

1
@gsl-팔로우 해 주셔서 감사합니다! stdin에서 읽는 것이 정말 유용하며 여전히 찾고 있습니다! 커맨드 라인에서 stdin을 명명 된 버퍼로 읽은 다음 elisp를 호출하여 여러 줄 버퍼를 변수로 읽습니다. 이것은 파이프에서 읽을 때 작동하지만 불행히도 stdin 스트리밍에는 적합 tail file |하지 않습니다 tail -f file |. 즉 작동하지만 작동하지 않습니다 . 노트를 살펴보고 부분적으로 작동하는 여러 줄 예제를 새로운 답변으로 추가하겠습니다. 알림 주셔서 감사합니다!
Melioratus
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.