이것을 어떻게 설명해야 할지 잘 모르겠지만, 제가 하고 있는 일을 설명하려고 노력하겠습니다. 나는 BASH
문자열을 전달하는 방법을 알아내려고 벽에 머리를 기대고 있었습니다 . {command:$1}
스크립트에 추가하고 $1
해당 값으로 채워지도록 합니다.
내가 시도하고 싶은 것은 출력을 json으로 변환하고, 스크립트를 사용하여 구문 분석하고 형식을 지정하고, 키와 값을 설정한 lsof
다음 원하는 열을 얻는 것입니다.awk
내 스크립트
#!/bin/bash
FORMAT=$1
(
IFS=' ';
while read line; do
set -- $line;
echo $FORMAT
done
)
내 명령줄 호출
lsof -Pn | grep LISTEN | awk '{print $1,$2,$3,$4,$5,$8,$9}' | ~/.scripts/json "{command:\$1,pid:\$2,user:\$3,fd:\$4,protocol:\$5:\$6,host:\$7}"
내 귀환
{command:$1,pid:$2,user:$3,fd:$4,protocol:$5:$6,host:$7}
슬래시를 제거하면
{command:,pid:,user:,fd:,protocol::,host:}
내가 뭘 기대하는 거지?
{command:webstorm,pid:5270,user:daviddiefenderfer,fd:142u,protocol:IPv4:TCP,host:127.0.0.1:6942}
정확히 무슨 일이 일어나고 있는지는 모르겠지만 이해하고 싶습니다. 변수는 $[1-7]
값이 없는 while 루프에 들어가기 전에 평가되고 있는 것 같습니다.
답변1
당신은 바퀴를 재발명하고 있습니다(그리고 잘못되었습니다). JSON을 생성하는 데 사용됩니다 jq
.
lsof -Pn |
awk '/LISTEN/ {print $1,$2,$3,$4, $5,$8,$9}' |
jq -R 'split(" ") |
{
command: .[0],
pid: .[1],
user: .[2],
fd: .[3],
protocol: "\(.[4]):\(.[5])",
host: .[6]
}'
귀하의 버전이 jq
정규식을 지원하는 경우 다음에 대한 호출을 제거할 수도 있습니다 awk
.
lsof -Pn | jq -R '
select(match("LISTEN")) |
[splits(" *")] |
{
command: .[0],
pid: .[1],
user: .[2],
fd: .[3],
protocol: "\(.[4]):\(.[7])",
host: .[8]
}'
답변2
$1, $2, ...
awk의 필드 접근자를 쉘의 $1, $2, ...
위치 매개변수 와 혼동하고 있습니다 . 게다가 파이프라인은 위치 매개변수를 설정하지 않고 단순히 왼쪽의 출력을 오른쪽의 입력으로 제공합니다.
JSON에는 객체 속성 이름을 포함하여 따옴표로 묶인 문자열 값이 필요하다는 점을 잊지 마세요.
json=$(
lsof -Pn | grep LISTEN \
| awk '
BEGIN {template = "{\"command\":\"%s\",\"pid\":\"%s\",\"user\":\"%s\",\"fd\":\"%s\",\"protocol\":\"%s:%s\",\"host\":\"%s\"}\n"}
{printf template, $1, $2, $3, $4, $5, $8, $9}
'
)
~/.scripts/json "$json"