키바인딩 없이 readline 기능을 실행하시겠습니까?

키바인딩 없이 readline 기능을 실행하시겠습니까?

나는 방금 readline 매뉴얼 페이지를 읽었고 존재하는지 몰랐던 멋진 명령들을 많이 발견했습니다. 그러나 일부에는 기본 키 바인딩이 없습니다. 쉘에서 바인딩되지 않은 명령을 실행하는 방법이 있습니까?

~/.inputrc에서 명령을 바인딩하는 방법을 묻는 것이 아니라 쉘이나 bash 스크립트에서 "한 번에" 명령을 실행하는 방법을 묻는 것입니다.

예를 들어 "변수 덤프" 명령이 있습니다. 실행할 인수로 "덤프 변수"를 제공할 수 있는 명령이 있습니까?

답변1

나는 당신이 찾고있는 것이 bind명령 자체라고 믿습니다. man builtin정보 에 따르면 실행을 bind <readline-command>사용하면 한 번에 실행할 수 있지만 설명서에 나와 있는 대로 작동할 수 없습니다... 계속해서 키가 작동하지 않게 되어 여행이 바뀔 수 있습니다. 나는 당신에게 유용할 수 있는 다음 명령을 찾았습니다.

bind -p # Equivalent to dump-functions [machine readable]
bind -P # Equivalent to dump-functions [human readable]

bind -s # Equivalent to dump-macros    [machine readable]
bind -S # Equivalent to dump-macros    [human readable]

bind -v # Equivalent to dump-variables [machine readable]
bind -V # Equivalent to dump-variables [human readable]

편집자 노트 매뉴얼에 나와 있는 대로 작동하지 않는다는 것이 얼마나 짜증나는지 지적하고 싶습니다. 왜냐하면 입력한 bind다음 탭 키를 눌러 자동 완성을 하면 모든 명령이 표시되기 때문입니다.

답변2

이것이 의미가 있는 한 가지 상황은 행이 비어 있을 때 기본 키 입력을 "오버로드"하는 것입니다. 이 경우 많은 바인딩이 의미가 없고 따라서 가장 편안한 키 입력 중 많은 부분이 매우 유용할 수 있지만 낭비되기 때문입니다. 그것은 마치

alt_n() {
    [ -z $READLINE_LINE ] && do_something_else || execute_default_command
}
bind -x '"\en": alt_n'

그렇지 않으면 영향을 받는 모든 바인딩에 대해 기본 동작을 구현해야 합니다. 이는 어떤 경우에는 매우 쉽고 다른 경우에는 그렇지 않으며 항상 이상한 버그가 발생하기 쉬운 해킹입니다. 실수로 세션을 계속 닫았기 때문에 실제로 작동하는 예(다행히 EOF가 처리되는 방식)가 stty eof ^B.profile에 있습니다. export IGNOREEOF=2이제 <C-B>커서가 떠나면 줄 편집기에서는 제대로 작동하지만 빈 프롬프트에서는 3번을 눌러 종료할 수 있습니다.

적어도 나에게는 혼란을 야기하지 않았으며 내가 명령을 입력하고 있는지 아니면 그냥 빈 줄에 앉아 있는지 항상 알고 있었습니다. 즉, 모든 프롬프트는 암시적으로 모달이므로 단축키 공간을 많이 낭비하고 일부 프롬프트를 보조 바인딩과 함께 사용하면 정말 깔끔할 것입니다. 구체적으로는 원래의 기능을 그대로 유지하면서 따로 <M-f>사용 <M-b>하고 싶어서 여기까지 왔습니다 .pushd +1pushd -1

나는 C 전문가는 아니지만 bash를 만지작거리는 것을 고려하고 있지만 그것은 불가능합니다.저것bind단일 인수를 허용하고 해당 readline 함수를 호출하도록 내장 함수를 확장하는 것은 어렵습니다 . 이미 이 작업을 수행한 사람이 있는지 궁금합니다.

답변3

나는 당신이 여기서 이론적인 문제를 간과하고 있다고 생각합니다.

readline 명령을 실행하는 것은 내용을 읽을 때만 의미가 있습니다. 그러나 bash 명령이 실행되면 bash는 일반적으로 더 이상 읽지 않습니다.

Readline은 bash와 독립적인 라이브러리입니다. 당신은 그것을 다음과 같이 사용합니다

// start reading 
char * input = readline("this is the prompt$ ");
// at this place, reading ended
// do something with input
free(input);

Readline은 실행 중에만 forward-word명령을 실행할 수 있습니다(예를 들어).readline()

입력 imaginary_cmd_for_executing_readline forward-word하고 bash엔터를 누르면 readline()종료되어 forward-word더 이상 실행할 수 없습니다. Bash의 소스 코드(또는 사용자 정의 로드 가능한 내장)에서 readline 명령을 따르는 C 함수를 직접 호출할 수 있습니다(예: rl_forward_word대신 forward-word또는 rl_get_previous_history대신 previous-history). 그러나 메모리 영역을 읽고 쓰기 때문에 실패할 수 있습니다. 그 때 사용하기 위해. 그렇더라도 라인 버퍼만 수정하고 실제로 아무것도 인쇄하지 않기 때문에 결과를 얻지 못할 것입니다.

readline()Bash는 런타임에 실행될 수 있는 일부 기능을 readline에 등록합니다 .

  • 신호가 도착합니다(예: 를 누를 때 ctrlc).
  • bash의 사용자 정의 readline 명령(예 shell-expand-line: ) 중 하나를 실행합니다. 이는 등록된 키 시퀀스를 입력한 경우에만 발생합니다.
  • bind -x등록된 키 시퀀스를 입력합니다.

이러한 후크에서는 이론적으로 readline 명령을 실행할 수 있습니다. 그러나 모두 키 입력 자체가 트리거로 필요하므로 직접 바인딩에 비해 사용하는 이점이 없습니다. 그러나 가장 중요한 것은 앞서 설명했듯이 줄을 편집하지 않고 readline 명령만 실행하는 것이 의미가 없을 수도 있다는 것입니다.

꼭 필요한 경우 실행하려는 명령에 키를 임시로 바인딩한 다음 해당 키 입력이 백그라운드에서 터미널 자체로 자동으로 전송되도록 할 수 있습니다.Bash가 자체 입력 스트림에 쓸 수 있나요?.

관련 정보