파이프에서 명령을 수신하는 bash 스크립트가 있습니다. 명령을 보면 실행합니다. 그러나 나중에 호출할 수 있는 bash 함수의 "사이드 로딩"을 지원했으면 좋겠습니다.
다음은 스크립트가 수행해야 하는 작업에 대한 아이디어를 제공하는 몇 가지 입력/출력 예제입니다.
# left of the arrow is input, right of arrow is output
"echo 'test'" -> "test"
"_a() { echo 'test' }" -> ""
"_a" -> "test"
일반 명령에서는 제대로 작동하지만 기능을 로드하는 데 문제가 있습니다. 나는 이것이 하위 쉘에서 사용자 입력을 실행하고 있기 때문에 부모가 정의된 함수를 사용하여 향후 명령을 실행할 수 없기 때문이라고 생각합니다. 파일 설명자를 사용하여 ( stdout
및 stderr
) 에 데이터를 저장하려고 시도했지만 eval
작동하지 못했습니다. 현재 다음과 같은 것이 있습니다.
exec 3>&1
eval 'echo "Hello World"' >&3
read -u 3 var
exec 3>&-
echo "$var"
가능합니까?
답변1
이것은 당신에게 도움이 될 수 있습니다:
$ cat runcmd
#!/usr/bin/env bash
tmpout=$(mktemp) || exit
tmperr=$(mktemp) || exit
trap 'rm -f -- "$tmpout" "$tmperr"; exit' EXIT
while IFS= read -r -a cmd; do
printf '==========\n'
declare -p cmd
eval "${cmd[@]}" > "$tmpout" 2>"$tmperr"
readarray -t out < "$tmpout"
readarray -t err < "$tmperr"
declare -p out
declare -p err
done
$ cat <<'EOF' | ./runcmd
echo 'test of echo with globbing * and variables $RANDOM and spaces'
_a() { echo 'test of a()'; }
_a
awk 'BEGIN{print "multi line\noutput string"; print "and multi\nline error\nmessage" | "cat>&2"}'
EOF
==========
declare -a cmd=([0]="echo 'test of echo with globbing * and variables \$RANDOM and spaces'")
declare -a out=([0]="test of echo with globbing * and variables \$RANDOM and spaces")
declare -a err=()
==========
declare -a cmd=([0]="_a() { echo 'test of a()'; }")
declare -a out=()
declare -a err=()
==========
declare -a cmd=([0]="_a")
declare -a out=([0]="test of a()")
declare -a err=()
==========
declare -a cmd=([0]="awk 'BEGIN{print \"multi line\\noutput string\"; print \"and multi\\nline error\\nmessage\" | \"cat>&2\"}'")
declare -a out=([0]="multi line" [1]="output string")
declare -a err=([0]="and multi" [1]="line error" [2]="message")
하지만 입력으로 제공된 코드를 실행하는 프로그램을 작성하는 것은 위험하므로 꼭 읽어보세요.Bash FAQ: 변수에 명령을 넣으려고 하는데 복잡한 경우에는 항상 실패합니다!그리고Bash에서 평가를 피해야 하는 이유와 무엇을 사용해야 합니까?이것을 구현하기 전에.