Como posso avaliar argumentos bash em uma string depois que as variáveis foram alteradas

0

não tenho certeza de como descrever isso, mas farei o possível para explicar o que estou fazendo. Eu estive BASH ing minha cabeça contra a parede tentando descobrir como passar uma string ex. {command:$1} em um script e faça com que ele preencha o $1 com seu respectivo valor.

O que estou tentando tentar é converter minha lsof output para json, pegando as colunas que quero depois de analisar com awk e formatando, definindo valores de chave com meu script.

Meu script

#!/bin/bash

FORMAT=$1
(
IFS=' ';
while read line; do
    set -- $line;
    echo $FORMAT
done
)

Minha chamada na linha de comando

lsof -Pn | grep LISTEN | awk '{print $1,$2,$3,$4,$5,$8,$9}' | ~/.scripts/json "{command:\,pid:\,user:\,fd:\,protocol:\:\,host:\}"

Meu retorno

{command:$1,pid:$2,user:$3,fd:$4,protocol:$5:$6,host:$7}

se eu remover as barras que recebo

{command:,pid:,user:,fd:,protocol::,host:}

O que estou esperando

{command:webstorm,pid:5270,user:daviddiefenderfer,fd:142u,protocol:IPv4:TCP,host:127.0.0.1:6942}

Não sei exatamente o que está acontecendo, mas eu adoraria entender, meu palpite é que as variáveis $[1-7] estão sendo avaliadas antes de entrar no loop while, onde não há valores.

    
por david 21.09.2017 / 15:59

2 respostas

1

Você está reinventando a roda (e incorretamente). Use jq para gerar seu JSON.

 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]
         }'

Se você tiver uma versão de jq compatível com expressões regulares, também poderá soltar a chamada para awk :

lsof -Pn | jq -R '
  select(match("LISTEN")) |
  [splits("  *")] |
  {
    command: .[0],
    pid: .[1],
    user: .[2],
    fd: .[3],
    protocol: "\(.[4]):\(.[7])", 
    host: .[8]
  }'
    
por 21.09.2017 / 19:10
0

Você está confundindo os acessadores de campo $1, $2, ... do awk com os parâmetros $1, $2, ... posicionais do shell. Além disso, um pipe não define parâmetros posicionais, apenas fornece a saída do lado esquerdo como a entrada para o lado direito.

Não se esqueça de que o JSON exige que os valores de string sejam citados, incluindo nomes de propriedades de objetos:

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"
    
por 21.09.2017 / 17:49