zsh 또는 bash를 사용하여 사용자에게 여러 명령을 요청하고 이를 함수로 저장할 수 있는 스크립트를 실행하고 싶지만 스크립트가 계속하기 전에 추가 입력을 기다리지 않기 때문에 직접 입력하지 않으면 eval "function $FNCNAME() {"
작동 하지 않는 것으로 나타났습니다. echo "function $FNCNAME() {" | zsh -is
. 다음 줄 또는 종료.
사용자 입력을 받아들이는 동안 스크립트 프로세스를 차단하고 사용자가 final(따옴표 없이)로 함수 정의를 끝낼 때만 계속하려면 어떻게 해야 합니까 }
?
요구사항은 다음과 같습니다.
- 쉘 자체의 컨텍스트 인식 자동 완성이 활성화되어 있습니다.
- 스크립트는 지연된 명령을 즉시 실행해서는 안 되지만, 새 함수의 정의를 호출하거나 인쇄할 수 있어야 합니다.
이 질문은 일반적인 배관 및 상호 작용 문제로 제한됩니다. 나는 다음을 요구하지 않습니다:
- 어떤 방식으로든 미리 작성된 명령을 스크립트에 제공하려면 어떻게 해야 합니까?
- "최고의 사용자 경험"을 제공하는 방법 또는 이를 개선하는 방법.
- 왜 이 문제를 해결하고 다른 일을 하면 안 될까요?
답변1
에서는 zsh
다음과 같이 보일 수 있습니다.
make-function() {
local psvar=$1
local line= body=
print -ru2 Please enter the definition of the $psvar function, one line at a time, terminate with an empty line.
while
line=
vared -p '%v> ' line
[[ -n $line ]]
do
body+=$line$'\n'
done
functions[$psvar]=$body
}
예를 들면 다음과 같습니다.
$ make-function f
Please enter the definition of the f function, one line at a time, terminate with an empty line.
f> echo test
f> return 42
f>
$ f
test
$ echo $?
42
$ functions f
f () {
echo test
return 42
}
다음과 같이 할 수도 있습니다.
vared 'functions[f]'
f
줄 편집기에서 함수 본문을 편집합니다. Enter편집기를 떠난 후 평소처럼 함수 본문에 리터럴 줄 바꿈을 입력하려면 Alt+ Enter또는 Esc뒤에 Enter(또는 bash의 readline에서와 같이 Ctrl+ v, Ctrl+ ) 가 필요합니다.j
vared
(변수 편집기)는 zsh 라인 편집기(zle)를 호출하여 변수의 내용을 편집하는 내장 함수이며 $functions
함수 이름을 해당 본문의 코드 표현에 매핑하는 특수 연관 배열입니다.
에서는 readline을 사용하여 편집하는 where를 사용하여 유사한 작업을 수행 bash
할 수 있으며 이름과 본문을 사용하여 함수를 생성할 수 있습니다.IFS= read -rep "$psvar> " line
-e
$line
eval "$psvar() { $body; }"
답변2
이게 당신이 하고 싶은 일인가요?
$ cat ./tst.sh
#!/usr/bin/env bash
tmp=$(mktemp) || exit 1
trap 'rm -f "$tmp"; exit' EXIT
fncname='foo'
printf 'List commands, terminated with Control-D\n' >&2
{
printf '%s () {\n' "$fncname"
while IFS= read -r line; do
printf '\t%s\n' "$line"
done
printf '}\n'
} > "$tmp" &&
. "$tmp"
declare -f "$fncname"
"$fncname"
$ ./tst.sh
List commands, terminated with Control-D
echo 'hello'
date
echo 'world'
<- I hit Control-D here
foo ()
{
echo 'hello';
date;
echo 'world'
}
hello
Wed Jan 3 15:48:38 CST 2024
world