저는 현재 Fluke DewK 1620a 온습도계에 연결하고 장치에서 현재 온도 및 습도 판독값을 추출하는 스크립트를 개발하려고 합니다. 이러한 장치에 네트워크 포트가 있지만 해당 포트를 수신하는 공통 프로토콜은 없는 것 같습니다. 그들은 원시 TCP 연결만 허용합니다. netcat과 putty를 통해 대화형으로 연결하고, 명령을 전달하고, 출력을 받을 수 있습니다. netcat을 통해 스크립트를 작성하려고 합니다.("netcat을 통해 Fluke 1620a에서 데이터 캡처" 참조), 그러나 전혀 작동하지 못했습니다. 그 이후로 저는 TCP 연결에서 읽기/쓰기를 위해 파일 설명자를 여는 Bash의 고유한 기능을 사용하여 작업을 수행할 수 있다는 사실을 발견했습니다. 이제 데이터를 파일로 캡처할 수 있지만 아마도 매우 기본적인 문제인 것으로 알고 있는 문제로 어려움을 겪고 있습니다.
#!/bin/bash
$host=1.2.3.4
$port=10001
$location=lab1
$log=${location}_DewK.log
$datetime=$(date +%F_%T)
exec 3<>/dev/tcp/${host}/${port}
echo -e "read?" >&3 # Sends the read? command to the Fluke.
printf ${datetime} >> ${log} # Inserts a timestamp to the log.
cat <&3 | tee -a ${log} & # Tee was the only way I could get it to log.
sleep 1 && pkill cat # The cat just hangs out there & will not end.
exec 3<&-
exec 3>&-
나는 그것이 추악하다는 것을 알고 있지만 그것을 더 효율적으로 만드는 방법을 알아낼 수 없는 것 같습니다. 내 주요 질문은 다음과 같습니다.
- "cat <&3"은 모든 종류의 문제를 일으킬 수 있습니다. EOF가 없으므로 영원히 정지됩니다. 나는 읽기를 통해 다양한 방법을 시도했지만 제대로 작동하지 않는 것 같습니다. "cat"은 데이터를 추출하여 파일에 쓸 수 있는 유일한 방법인 것 같지만 센서를 독차지하는 것을 방지하려면 "pkill"을 사용해야 합니다.
- 결과를 $results와 같은 변수로 읽고 싶지만 "cat"을 사용하면 이를 달성할 수 없는 것 같습니다. 나는 매우 간단한 것을 놓치고 있다고 생각하지만 그것을 알아낼 수 없는 것 같습니다.
Fluke의 출력은 "76.05,56.3,72.89,59.0^M"과 같습니다. EOL을 감지하지 못하기 때문이라는 것을 알고 있지만 "cat <&3" 뒤에 새 줄을 추가하는 방법을 모르겠습니다. 결과는 다음과 같은 로그입니다.
2014-11-26_07:09:03
75.75,56.4,72.53,59.7^M2014-11-26_07:09:05
75.75,56.4,72.54,59.7^M2014-11-26_07:09:07
75.75,56.4,72.53,59.7^M
내 목표는 실행할 때마다 로그 파일의 한 줄에 "${datetime} - ${results}"를 쓰는 것이지만 줄을 결합하는 방법을 모르겠습니다. 대답은 내가 사용할 수 있는 변수에 결과를 넣는 데 있다고 생각합니다.
제가 받을 수 있는 도움을 주시면 감사하겠습니다. 나는 매뉴얼 페이지, bash 문서, 블로그 게시물, 그리고 물론 이 웹사이트를 살펴보았습니다. 제가 여기에서 수집한 정보가 제가 이 지경에 이르게 된 유일한 이유입니다. 나는 단순히 내 깊이를 벗어나 충돌 코스에 있었습니다.
답변1
read?
결과당 하나의 결과를 얻는지 , 아니면 여러 결과를 얻는지는 확실하지 않습니다 . 요청 -> 답변을 말씀하시는 것 같은데요. 그리고 16진수 덤프나 출력을 제공한 적이 없지만 줄 끝이 DOS CR-LF나 unix LF가 아닌 그냥 CR인 것처럼 보입니다. (이것이 나중에 프롬프트가 netcat의 출력을 무시하는 이유입니다.)
나는 매뉴얼을 찾았습니다 : http://us.flukecal.com/literature/product-manuals/1620a-user%E2%80%99s-guide
CR로 응답이 종료되었음을 확인합니다. 이것은 cat과 동일한 문제가 있기 때문에 쉘에서 사용하는 것을 고통스럽게 만듭니다 tr '\r' '\n'
. 한 줄 이후에 멈추지 않습니다.
# read -d sets the delimiter.
# $'' is a special type of quoting where \r expands to a literal carriage return.
get_temp () { # io to fluke on FD 3
echo "read?" >&3
local resp
IFS= read resp -d $'\r' -u 3
printf '%s\n' "$resp"
}
exec 3<>"/dev/tcp/$host/$port"
while true; do # whole loop is redirected to log
temp="$( get_temp )"
printf '%s - %s\n' "$(date +%F_%T)" "$temp"
# or echo -n "$(date) - "; get_temp
sleep 1
done | tee -a "$log"
# or just >> "$log", and tail -f the log file when you want it on screen.
tr
또는 CR -> LF 변환을 처리하는 구현:
exec 3<>"/dev/tcp/$host/$port"
(while echo 'read?';do sleep 1;done >&3) &
tr -d '\r' '\n' <&3 | IFS= while read temp; do
printf '%s - %s\n' "$(date +%F_%T)" "$temp"
done >> "$log"
이렇게 하면 매초마다 명령을 작성하는 하위 쉘이 백그라운드에 배치됩니다. 현재 시간을 수신된 행으로 형식화하려면 여전히 읽기 루프가 필요합니다. ^C가 서브쉘을 죽일지는 모르겠습니다.
루프 내에 설정된 변수는 루프가 끝난 후에는 나타나지 않습니다.우리가 그것을 파이프로 넣었기 때문에, 시도해 보고 싶다면.
이것은 오래된 질문이므로 실제로 실행하지 않았습니다. 문법적 오류나 실수가 있을 수 있습니다. 그러나 나는 전반적인 아이디어가 타당하다고 확신합니다.