대화형 bash 스크립트: 모든 줄에 문자열 접두사 추가

대화형 bash 스크립트: 모든 줄에 문자열 접두사 추가

Bash에서 대화형 CLI를 만들고 싶습니다. bash가 각 줄에 접두사를 붙이는 방식과 유사하게 user@host:~$, 나는 각 줄에 접두사를 붙이고 싶습니다 foobar>. 이 기능은 Metasploit 또는 mysqli와 같은 CLI 애플리케이션에서 볼 수 있지만 이들은 별도의 프로그래밍 언어를 사용하는 반면 저는 bash 스크립트만 사용하고 싶습니다. 또한 history사용자가 마지막 입력이나 n번째 이전 입력을 쉽게 불러올 수 있는 기능(또는 이와 유사한 것)을 사용하려면 위쪽/아래쪽 화살표 키가 필요합니다 .

솔루션을 만들려고 노력하는 동안 나는 우연히 발견했습니다.이 답변이는 bash가 화살표 키를 해석하고 이를 사용하여 마지막 입력을 불러올 수 있게 해줍니다 history. 이것은 작동하지만 행 접두사와 결합하는 데 문제가 있습니다. 해결책을 찾았습니다여기그러나 coproc을 사용하여 stdout을 전처리하고 입력 중인 입력 줄이나 화살표 키를 사용하여 뽑아낸 줄에서 작동하지 않는 이 메서드 버전을 구현하세요 history. 지금까지 내 bash 스크립트는 다음과 같습니다.

exec 4>&1
coproc out (sed 's/^/foobar> /' >&4)
exec 1>&${out[1]}

printf "foobar> " >&4
while read -e x; do
   history -s "$x"
   echo $x
done

다음은 두 가지 문제를 자세히 설명하는 출력입니다. 아래에서 볼 수 있듯이 printf "foobar> " >&4위 스크립트에서 while 루프 앞에 사용하여 cli의 첫 번째 줄 앞에 접두사를 붙일 수 있었습니다 . 아래에 boop첫 번째 줄을 입력하면 echo의 출력이 내 coproc로 리디렉션됩니다. 그러나 그 후에 위쪽 화살표를 사용하여 입력을 다시 가져오면 내 접두사 없이 boop인쇄됩니다 boop(마지막 줄에 표시됨).

$ ./test.sh
foobar> boop
foobar> boop
boop

나는 루프 내부에 printf가 없었기 때문에 내가 입력한 줄이 첫 번째 반복 이후에 접두사가 붙지 않았다는 것을 깨달았습니다. 나중에 루프를 다시 처리하여 이 문제를 해결할 수 있습니다(비록 접두사가 붙은 행을 접두사가 붙은 coproc으로 보내 이중 접두사가 붙는 것이 걱정되지만). 내가 고쳐야 할 가장 중요한 것은 위쪽 화살표 출력입니다.아니요접두사를 가져옵니다. 나는 메시지가 를 통해 전송되었다고 가정했지만 stdout분명히 그렇지 않았습니다. 또한 동일한 방식으로 리디렉션을 시도했지만 stderr이렇게 하면 내가 입력할 때 터미널에서 입력한 내용이 에코되는 것을 방지할 수 있습니다.

위에서 제공한 스크립트를 기반으로 구축되었거나 다른 접근 방식을 사용하는지 여부에 관계없이 bash 스크립트의 모든 줄에 접두사를 추가하는 솔루션이 필요합니다. 또한 이 기술을 사용하여 CLI 도구를 구축하고 추가 오버헤드를 가능한 한 적게 원하기 때문에 가능한 한 우아해지기를 원합니다. 나는 리디렉션이 이 작업을 수행할 것이라고 생각했지만 분명히 처음에 생각했던 것보다 더 복잡했습니다.

ベストアンサー1

나는 그것에별로 관심을 기울이지 않았습니다 coproc. 귀하의 경우에는 read -p맞는 것 같습니다 . 별도의(기본값이 아닌) 기록 파일을 사용할 수 있습니다.

경고: $HOME/.custom_history기록을 저장하기 위해 스크립트가 생성/사용되었습니다. 솔루션을 테스트한 후 파일을 수동으로 삭제하세요.

#!/bin/bash

# History management
hfile="$HOME/.custom_history"
HISTCONTROL=ignoreboth
history -r "$hfile"
trap 'history -a "$hfile"' exit

# Main loop
while read -ep 'foobar> ' x; do
   history -s -- "$x"
   printf '%s\n' "$x"
done

기본 아이디어는 다음에서 빌려왔습니다.이 문제.

おすすめ記事