not really sure how to describe this but I'll do my best to explain what I'm doing. I've been BASHing my head against the wall trying to figure out how to pass a string ex. {command:$1} into a script and have it populate the $1 with it's respective value.

What i'm trying to attempt is converting my lsof output to json, grabbing the columns I want after parsing with awk and formatting, setting key, values with my script.

My Script


IFS=' ';
while read line; do
    set -- $line;
    echo $FORMAT

My command line call

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}"

My return


if I remove the forward slashes I get


What I'm expecting


I'm not sure what exactly is happening but I would love to understand, my guess is that the variables $[1-7] are being evaluated before they get into the while loop, where there is no values.


You are reinventing the wheel (and incorrectly). Use jq to generate your 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]

If you version of jq supports regular expressions, you can drop the call to awk as well:

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

You are confusing awk's $1, $2, ... field accessors with the shell's $1, $2, ... positional parameters. Also, a pipe does not set positional parameters, it just provides the output from the left-hand side as the input to the right-hand side.

Don't forget that JSON requires string values to be quoted, including object property names:

    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"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.