변수 확장 중에 >(리디렉션)에 작은 따옴표를 추가하는 bash(리디렉션 중단)

변수 확장 중에 >(리디렉션)에 작은 따옴표를 추가하는 bash(리디렉션 중단)

조사한 결과 이것이 bash 스크립트에서 가능한지 확실하지 않습니다. 내가 찾은 가장 가능성 있는 원인은 bash의 쉘 확장 순서였습니다. (아마도?)

내가 무슨 일이 일어나길 원하는지, >이전 변수를 통한 명령문 리디렉션을 활성화/비활성화하는 기능 ( ).

예를 들어 아래 printf 출력은 >변수 $SendGrafana에 포함된 내용에 따라 리디렉션되어야 합니다.
하지만 이 예제 코드는 작동하지 않습니다.

SendGrafana=" > /dev/tcp/192.168.1.242/5062"

awk -v vars="$vars" 'BEGIN{printf "output.api %s \n", vars;}' $SendGrafana

위의 코드가 다음과 같이 작동하기를 원합니다.

awk -v vars="$vars" 'BEGIN{printf "output.api %s \n", vars;}' > /dev/tcp/192.168.1.242/5062

또한 - 디버깅을 위해 set -x를 사용하여 스크립트를 실행할 때 리디렉션(>) 주위에만 작은따옴표(')가 표시됩니다. 이는 내 netcat 스파이 청각 장치로 아무 것도 전송되지 않기 때문에 문제라고 생각합니다. 이것은 set -x를 사용할 때 가독성을 높이기 위한 것이라고 읽었지만 문제는 지속됩니다.

set -x가 활성화된 경우 관련 출력은 다음과 같습니다.

+ awk -v vars=3 'BEGIN{printf "output.api %s \n", vars;}' '>' /dev/tcp/192.168.1.242/5062

(참고 ">")

변수 선언과 변수 확장 모두에서 많은 것을 시도했지만 스크립트를 호출할 때 출력을 192.168.1.242:5062로 리디렉션할 수 없습니다. 감사해요


다음과 같이 편집되었습니다 - (질문을 짧게 유지하려고 하기 때문에 내 의견에 이 부분을 추가하지만 제안 사항은 여기에 있어야 합니다):

$SendGrafana더 많은 컨텍스트 추가: 각 awk 문 뒤에 변수를 사용하지 않고 그대로 사용하는 것과 달리 이 변수를 사용하는 이유 > /dev/tcp/192.168.1.242/5062는 쉽게 설정할 수 있도록 하기 위함이며 $SendGrafana= " "스크립트는 192.168.0으로 보내는 대신 STDOUT으로 출력됩니다. 1.242 > /dev/tcp/192.168.1.242/5062). 새 문을 추가하는 디버깅/테스트 중에 STDOUT에 대한 출력만 필요합니다.

답변1

문제는 실제로 평가 순서입니다.

이것은 단지 명령줄에 텍스트를 넣는 것입니다. 쉘이 리디렉션을 구현하기에는 너무 늦었습니다.

paul $ j=" > foo.txt "
paul $ echo Words Here $j
Words Here > foo.txt
paul $ ls -l foo.txt
ls: cannot access 'foo.txt': No such file or directory

이로 인해 쉘은 전체 명령을 재평가하게 됩니다.

paul $ eval echo Words Here $j
paul $ ls -l foo.txt
-rw-r--r-- 1 paul paul 11 Aug 19 22:38 foo.txt
paul $ cat foo.txt
Words Here
paul $ 

내장된 평가판은 올바르게 사용하기 어려울 수 있으므로 가능하면 사용하지 않습니다. 명령은 두 번(eval에 대한 인수로 한 번, eval 자체에 의해 한 번) 평가되므로 인용이 어렵고 지루해질 수 있습니다(특히 이미 작은따옴표와 큰따옴표가 필요한 awk가 포함된 경우). 또한 오류가 발생할 수 있습니다. 변수가 명령으로 실행되어 의도하지 않은 결과가 발생합니다. 자세한 내용은 여기를 참조하세요:

unix.stackexchange.com/questions/278427/why-and-when-should-eval-use-be-avoided-in-shell-scripts

추가된 예:

내가 게시한 StackExchange 링크의 제안 중 하나는 쉘이 새 파일 설명자를 생성한 다음 먼저 대상으로 전달하도록 하는 것이었습니다.

이것은 다소 과장된 테스트 스크립트입니다.

#! /bin/bash

#.. First arg to script is -l for test runs.

#.. For your live action.
Grafana="/dev/tcp/192.168.1.242/5062"

#.. For my demo here.
Grafana="./foo.txt"

rm -f foo.txt

if [[ "${1}" = "-l" ]]; then
    exec 7>&1
    shift 1
else
    exec 7>"${Grafana}"
fi  
 
vars="${@}" #.. Rest of args to output.

awk -v vars="$vars" 'BEGIN{printf "output.api %s \n", vars;}' 1>&7

ls -l foo.txt && cat foo.txt

테스트하려면 터미널에 로그인한 다음 명명된 파일/장치에 로그인하세요.

Paul--) ./Swit -l Easy Living
output.api Easy Living 
ls: cannot access 'foo.txt': No such file or directory
Paul--) ./Swit Easy Living
-rw-r--r-- 1 paul paul 24 Aug 20 09:22 foo.txt
output.api Easy Living 
Paul--) 

fd 7을 열어두고 스크립트에서 여러 번 사용할 수 있습니다. 다음 명령으로 끌 수 있습니다exec 7>&-

관련 정보